Regex 使用正则表达式递增整数的匹配列表

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))是谓词的占位符,确保

是否可以匹配逗号分隔的十进制整数列表,其中列表中的整数总是递增1

这些应匹配:

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)