【问题标题】:regex - catch two numbers, make sure the second one is larger正则表达式 - 捕获两个数字,确保第二个更大
【发布时间】:2014-05-30 15:26:11
【问题描述】:

我需要一个正则表达式代码来匹配一组数字,但前提是第二个数字更大。数字以x,y的格式出现,如果y > x,我需要匹配它。

捕捉任意长度的数字都很容易:

/([0-9]*),([0-9]*)/

目前,它将捕获x,y 格式的任何内容(如果 x 和 y 是数字)。看看那里的其他例子,我尝试做这样的事情:

/([0-9]*),([0-9]*)(?>=\1)/

我很确定我的方向是正确的,那里的\1 引用了第一组,但我不确定如何进行比较。你能帮助我吗?

提前致谢!

附言 这是指向regexr demo 的链接以及一些示例。如您所见,目前一切都已匹配。

【问题讨论】:

  • 用正则表达式做不到
  • 您使用什么语言?您可以捕获两个数字,然后使用回调来过滤结果。您可能还想阅读我以前的answer。
  • 正则表达式用于匹配模式,而不是评估数值。
  • @HamZa 我知道。但是对于我的用例来说,正则表达式会更容易,因为我需要以字符串形式传递验证信息(函数等需要预先配置验证,我需要一个更通用的解决方案)
  • 您的正则表达式必须定义所有有效数字对的域。

标签: regex


【解决方案1】:

正则表达式匹配,它们不比较

纯正则表达式不能“比较”数字。您实际上必须经历并制作每个可能的场景,类似于how you allow a range of numbers。


这是一个匹配X,Y 的简单示例,其中X < Y 和X < 10,如果你愿意,你可以想象比这更高..

\b(?:[0-9],[1-9][0-9]+|0,[1-9]|1,[2-9]|2,[3-9]|3,[4-9]|4,[5-9]|5,[6-9]|6,[7-9]|7,[8-9]|8,9)\b

Expanded Demo

在这里你可以看到我首先说如果下一个数字是 [1-9] 后跟至少一个数字(十、百、千等的数字),则任何一位数字 [0-9] 都可以匹配。然后我们使用交替来查看每个数字后面可以跟什么(4 < [5-9])。如果您想走得更高,您不仅需要继续扩展,而且您还需要对负数执行逆逻辑。这一切都包裹在一个非捕获组中,两边都有单词边界。


让我们玩得开心,为0 <= X < 100 工作。我还是用了一些捷径:

  • [1-9][0-9],[1-9][0-9]{2,} 为10+ < 100+
  • 然后每 10 秒我为10-19 < 20+ 做1[0-9],[2-9][0-9]+
  • 但我们仍然需要单独定义每一列

我们最终得到了相当多的monster regex,因为我们只计算了 100 个数字。此外,如果您对此进行调试,您将看到在一些大数字上步数增加到 500。这是我们的 951 字符表达式:

\b(?:[0-9],[1-9][0-9]+|0,[1-9]|1,[2-9]|2,[3-9]| 3,[4-9]|4,[5-9]|5,[6-9]|6,[7-9]|7,[8-9]|8,9|[1-9][ 0-9],[1-9][0-9]{2,}|1[0-9],[2-9][0-9]+|21,2[2-9]|22, 2[3-9]|23,2[4-9]|24,2[5-9]|25,2[6-9]|26,2[7-9]|27,2[8-9 ]|28,29|2[0-9],[3-9][0-9]+|11,1[2-9]|12,1[3-9]|13,1[4-9 ]|14,1[5-9]|15,1[6-9]|16,1[7-9]|17,1[8-9]|18,19|3[0-9],[ 4-9][0-9]+|31,3[2-9]|32,3[3-9]|33,3[4-9]|34,3[5-9]|35,3 [6-9]|36,3[7-9]|37,3[8-9]|38,39|4[0-9],[5-9][0-9]+|41,4 [2-9]|42,4[3-9]|43,4[4-9]|44,4[5-9]|45,4[6-9]|46,4[7-9] |47,4[8-9]|48,49|5[0-9],[6-9][0-9]+|51,5[2-9]|52,5[3-9] |53,5[4-9]|54,5[5-9]|55,5[6-9]|56,5[7-9]|57,5[8-9]|58,59| 6[0-9],[7-9][0-9]+|61,6[2-9]|62,6[3-9]|63,6[4-9]|64,6[ 5-9]|65,6[6-9]|66,6[7-9]|67,6[8-9]|68,69|7[0-9],[8-9][0 -9]+|71,7[2-9]|72,7[3-9]|73,7[4-9]|74,7[5-9]|75,7[6-9]| 76,7[7-9]|77,7[8-9]|78,79|8[0-9],9[0-9]+|81,8[2-9]|82,8[ 3-9]|83,8[4-9]|84,8[5-9]|85,8[6-9]|86,8[7-9]|87,8[8-9]| 88,89|91,9[2-9]|92,9[3-9]|93,9[4-9]|94,9[5-9]|95,9[6-9]|96 ,9[7-9]|97,9[8-9]|98,99)\b

【讨论】:

  • 我不需要负数或浮点数,我可能可以设置一个特定的限制,就可以了。所以,是的,这是一个很好的答案,谢谢!
  • 你可能会做一些 for 循环来自动通过并创建这个字符串。你走的越高,你能做的增强就越多,比如:1[0-9],(?:[2-9][0-9]+|[1-9][0-9]{2,})跨度>
  • 哦,但是有一个问题(很抱歉把正确的带走了)——我最多只需要说 2-3 位数字。但是,如果我在10,20 上使用您的正则表达式,它将匹配0,20,这对我不利。它也匹配21,12,这也是错误的
  • @yuvi 查看我使用单词边界的更新(它执行零长度断言来检查单词字符是否在非单词字符 (^\w|\w\W|\W\w|\w$) 旁边)
  • 更好,但现在如果第一个数字是两位数,它就不起作用了。如果我们可以对match a number higher than some arbitrary x 使用正则表达式,我们不能以更通用的形式使用它吗?说使用第一个号码配置第二个号码的限制?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-03
  • 2014-09-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多