Regex 使用正则表达式递增整数的匹配列表
是否可以匹配逗号分隔的十进制整数列表,其中列表中的整数总是递增1 这些应匹配:Regex 使用正则表达式递增整数的匹配列表,regex,pcre,Regex,Pcre,是否可以匹配逗号分隔的十进制整数列表,其中列表中的整数总是递增1 这些应匹配: 0,1,2,3 8,9,10,11 1999,2000,2001 99,100,101 这些不应匹配(整体-后两个具有匹配的子序列): 是的,当使用支持反向引用和条件的正则表达式引擎时,这是可能的 首先,可以将连续数字的列表分解为一个列表,其中每对数字是连续的: (?=(?&cons))\d+ (?:,(?=(?&cons))\d+)* ,\d+ 这里,(?=(?&cons))是谓词的占位符,确保
0,1,2,3
8,9,10,11
1999,2000,2001
99,100,101
这些不应匹配(整体-后两个具有匹配的子序列):
是的,当使用支持反向引用和条件的正则表达式引擎时,这是可能的 首先,可以将连续数字的列表分解为一个列表,其中每对数字是连续的:
(?=(?&cons))\d+
(?:,(?=(?&cons))\d+)*
,\d+
这里,(?=(?&cons))
是谓词的占位符,确保两个数字是连续的。此谓词可能如下所示:
(?<cons>\b(?:
(?<x>\d*)
(?:(?<a0>0)|(?<a1>1)|(?<a2>2)|(?<a3>3)|(?<a4>4)
|(?<a5>5)|(?<a6>6)|(?<a7>7)|(?<a8>8))
(?:9(?= 9*,\g{x}\d (?<y>\g{y}?+ 0)))*
,\g{x}
(?(a0)1)(?(a1)2)(?(a2)3)(?(a3)4)(?(a4)5)
(?(a5)6)(?(a6)7)(?(a7)8)(?(a8)9)
(?(y)\g{y})
# handle the 999 => 1000 case separately
| (?:9(?= 9*,1 (?<z>\g{z}?+ 0)))+
,1\g{z}
)\b)
第一个块将捕获数字是否是N到组aN中,第二个块将使用条件来检查使用了这些组中的哪一个。如果组A为非空,则下一位数字应为N+1
第一个案例的其余部分处理类似于19992000
的案例。这同样属于模式n9^N,N+10^N
,因此这是匹配a^nb^N
和递增十进制数字的方法的组合。1,2
的简单情况作为极限情况处理,其中n=0
完整正则表达式:
或者,如果支持递归子模式引用,则可以更直接地实现
(?&cons)
谓词:
(?<cons>\b(?:
(?<x>\d*)
(?:(?<a0>0)|(?<a1>1)|(?<a2>2)|(?<a3>3)|(?<a4>4)
|(?<a5>5)|(?<a6>6)|(?<a7>7)|(?<a8>8))
(?<y>
,\g{x}
(?(a0)1)(?(a1)2)(?(a2)3)(?(a3)4)(?(a4)5)
(?(a5)6)(?(a6)7)(?(a7)8)(?(a8)9)
| 9 (?&y) 0
)
# handle the 999 => 1000 case separately
| (?<z> 9,10 | 9(?&z)0 )
)\b)
(?\b(?:
(?\d*)
(?:(?不错的帖子。我有一个关于在正则表达式中嵌套回引用这个表达式的一般性问题,例如(?\g{y}+0)
。我使用的是Boost正则表达式引擎,它主要与PCRE和Perl兼容。有时我不得不在某些情况下使用变通方法。例如(?(?&\y)+0)(?(DEFINE)(?\g{y}))
有时会因为未定义的backref
消息而让我发疯,如果可以制定解决方案,为什么不直接支持它。不知道您是否知道不需要函数调用的更好的解决方案?(解决方案)@sln抱歉,不熟悉boost正则表达式引擎。如果我理解正确,问题是boost不支持对尚未(完全)返回的组的反向引用匹配了吗,对吗?在这种情况下,您的解决方案似乎是合理的。我还添加了一个基于递归子模式引用的替代解决方案,可能是现成的解决方案……在解析过程中是编译时:尚未(完全)匹配的组已解析。
。因此引用的是它的父捕获组。我解决了这个问题,在组打开时允许对该标记进行反向引用,但在通过递归解析添加内部状态之前。以前,它只允许在关闭时对该标记进行反向引用。)
已被解析。这是一个简单的位掩码m_backrefs |=1Congrats。您成功地使用字符串操纵器系统进行了数学运算。@ThomasAyoub-这实际上不是数学本身。如果OP使用Perl,则可以通过代码断言的(?{})
以相当简单的方式在正则表达式中完成实际的数学运算。
(?:(?<a0>0)|(?<a1>1)|(?<a2>2)|(?<a3>3)|(?<a4>4)
|(?<a5>5)|(?<a6>6)|(?<a7>7)|(?<a8>8))
(?(a0)1)(?(a1)2)(?(a2)3)(?(a3)4)(?(a4)5)
(?(a5)6)(?(a6)7)(?(a7)8)(?(a8)9)
(?<cons>\b(?:
(?<x>\d*)
(?:(?<a0>0)|(?<a1>1)|(?<a2>2)|(?<a3>3)|(?<a4>4)
|(?<a5>5)|(?<a6>6)|(?<a7>7)|(?<a8>8))
(?<y>
,\g{x}
(?(a0)1)(?(a1)2)(?(a2)3)(?(a3)4)(?(a4)5)
(?(a5)6)(?(a6)7)(?(a7)8)(?(a8)9)
| 9 (?&y) 0
)
# handle the 999 => 1000 case separately
| (?<z> 9,10 | 9(?&z)0 )
)\b)