正则表达式:数字范围

32

你如何编写一个正则表达式来匹配从0或000到180的数字范围?


1
http://www.regular-expressions.info/numericranges.html 是一篇非常有用的文章。 - Bergi
我相信你可以使用这个包https://github.com/dimka665/range-regex。它已经支持负值。当前的代码没有更新,所以你需要从该Github资源下载它。 - swdev
9个回答

36

我认为正则表达式不是这个问题的正确选择。你是否尝试解析该值?如果必须使用正则表达式,我建议匹配\d{1,3},解析字符串,然后在代码中验证数字。


8
其他答案每个都至少有一个bug,这就是为什么不值得使用正则表达式来完成这些任务的原因。 - soulmerge
3
两个缺陷 :( 但是,是的,我基本上同意。 - Joey
1
在其他情况下,解析一个值可能更容易,但它被用于一个较大的正则表达式,该正则表达式传递类似于54°11'56.234''的坐标。 - Morten
3
在这种情况下,将坐标的各个部分分别捕获到一个捕获组中,并在之后验证它们。 - Joey
1
在我看来,这是正确的答案。试图仅使用正则表达式来解决这些问题的人会给自己(以及接下来的人)带来不便。 - paxdiablo

31

最简单的方法是将该字符串解析为数字,并查看数字是否在正确的范围内。

要使用纯正则表达式进行此操作,您需要识别模式并将其编写出来:

^(0?[0-9]{1,2}|1[0-7][0-9]|180)$

这有三种选择:第一种适用于单个和两位数字(允许前导零),其中每个数字可以是0到9的任何数字。还有一种指定三位数中每个数字允许的数字范围的方法。在这种情况下,这意味着第一个数字需要是1,第二个数字在0到7之间,最后一个数字可以是任何数字。第三种选择仅适用于数字180,因为它不适合其他模式。

更直接的方法可能是

^(0{0,2}[0-9]|0?[1-9][0-9]|1[0-7][0-9]|180)$

它只是在可能存在棘手的数字范围时进行交替。


这就是诀窍。正如您所提到的,它必须匹配三位数字,如001、010、012等,这个程序可以做到。谢谢! - Morten

18

最近发布的 rgxg 命令行工具可以生成匹配特定数字范围的正则表达式:

$ rgxg range -Z 0 180
(180|1[0-7][0-9]|0?[0-9]{1,2})

更多信息请参见https://rgxg.github.io


3

我的建议:

任何回答这个问题的人都应该使用以下输入测试他们的正则表达式

应匹配:0、00、000、5、05、005、95、095、180

不应匹配:0000、0095、181、190

我认为Johannes Rössel所写的内容是最好的:

^(0?[0-9]{1,2}|1[0-7][0-9]|180)$

1
PowerShell 可以帮助验证:-20..200|%{$_;"{0:00}"-f$_;"{0:000}"-f$_}|%{if ($_-match"^(0?[0-9]{1,2}|1[0-7][0-9]|180)$"){Write-Host -fore green $_}else{Write-Host -fore red $_}} - Joey

2

试试这个:

^(0|[1-9][0-9]?|1[0-7][0-9]|180)$

@Ionut G. Stan:我认为这只是一种备选方案,如果只匹配没有前导零的数字太困难了。 - Gumbo

1

我会将范围分解,以便可以轻松地在单独的正则表达式中指定:

^(0|0[0-9][0-9]|1[0-7][0-9]|180)$

或者,用人类可读的术语来说:

0
000-099
100-179
180

如果您需要两位数的范围,只需将[0-9][0-9]添加到正则表达式中即可。

此外,如果您在使用正则表达式时遇到问题,请尝试以尽可能清晰的方式指定它们的运算符 - 通常有一种方法可以以使其功能更加清晰的方式表示它们,特别是如果您所使用的语言允许您将正则表达式规范的部分分开成不同的列和行。


你忘记了单个数字1到9。 - Robert L
不,我只是读到“0或000至180”,并理解为:0作为一个数字,或范围000至180作为三个数字。当我说“如果你需要两位数范围……”我也应该提到一位数范围,所以就这方面而言,你是正确的。 - lcv

0

如果您不关心负数

>> r = /\b(0?\d?\d|1[0-7]\d|180)\b/
=> /\b(0?\d?\d|1[0-7]\d|180)\b/
>> (0..200).map {|i| i.to_s =~ r }
=> [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil]
>> 

0
你可以使用以下正则表达式。
^([0-1]?[0-7]?[0-9])|180$

如果您需要确切的三位数字,可以删除问号标记。 - Amjad Sham

0

我修改了Gumbo的:

^(00?0?|0?[1-9][0-9]?|1[0-7][0-9]|180)$

试一下。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接