正则表达式-如何在Lookbehind中使用“第n个捕获组”(\ n)表达式?

时间:2019-07-11 21:08:25

标签: regex regex-lookarounds regex-group

是否可以在正则表达式Lookbehind中使用“第n个捕获组”表达式(即“ \ 1”,“ \ 2”,“ \ 3”等)?

类似这样的内容:(?<=\1)([a-z])

我知道可以在前瞻中使用它:([a-z])(?=\1)

我正在使用在线工具测试我的正则表达式模式,当我在Lookbehind中使用'\ n'表达式时,它会不断给我带来错误。

这使我认为它要么需要特殊的语法,要么就不可能。

如果确实无法在Lookbehind中使用'\ n'表达式,是否有其他替代方法同样适用?

编辑:我的目标是能够动态地测试当前字符之前的字符。

我的特定用例是,我要搜索的所有字符都与其自身相同或相同。

例如,给定以下字符串:

// Should match 'b', because it is neither followed nor preceded by a 'b'.
// Should match 'd' for the same reason
aabccd 

// Should match 'y'
xxyzz

// Should match 'l' and 'o'
lmmmnnopppp

我发现执行此操作的最佳方法是使用([a-z])匹配所有字符,但只能使用(?<!\1)选择不以相同字符开头且不以相同字符开头的字符字符使用:(?!\1)

完整的模式如下所示:/(?<!\1)([a-z])(?!\1)/g

但是,如果在Lookebehind断言中不能使用“第n个捕获组”表达式,并且没有等效替代项,那么我将不得不寻找另一种策略。

1 个答案:

答案 0 :(得分:2)

如果您检查此正则表达式(a.*).+?(?<!\1)..
您会看到捕获组1的长度可以可变。

因此,大多数仅支持 固定宽度的正则表达式引擎
在断言后面查看,不会让您使用反向引用
内在断言的背后。即使捕获组是固定的(a)
它仍然不会让你这样做。


替代方法因情况而异,但通常涉及使用前瞻性断言。


前进

(?<=\1)([a-z])直接等效于(?<=([a-z]))\1

更新

  

编辑:我的目标是能够动态测试当前字符之前的字符。

     

我的特定用例是,我要搜索的所有字符都与其自身相同或相同。

您可以通过两种几乎相同的方法来实现。
它们都需要对边界进行额外检查
在后面看,向前看是没有问题的。

大多数人都不知道您可以嵌入/嵌套断言
就像改变方向一样有效 通过实际运行在单独的堆栈上进行检查
它是自己的代码位置以及所有内容。

这使您可以执行以下棘手的工作:

方法1 -使用分支重置(?| )
没什么特别的,它只是重用了常见的捕获组。
只是更容易阅读。需要PCRE或Perl或Ruby。

(?|(?<=\b()(?=([a-z])))\2(?!\2)|(?<=([a-z])(?!\1)(?=([a-z])))\2(?!\2))

https://regex101.com/r/s6Z8uV/1

扩展

 (?|
      (?<=
           \b 
           ( )                           # (1)
           (?=
                ( [a-z] )                     # (2)
           )
      )
      \2 
      (?! \2 )
   |  
      (?<=
           ( [a-z] )                     # (1)
           (?! \1 )
           (?=
                ( [a-z] )                     # (2)
           )
      )
      \2 
      (?! \2 )
 )

方法2 -没什么特别的。

(?:(?<=\b()(?=([a-z])))\2(?!\2)|(?<=([a-z])(?!\3)(?=([a-z])))\4(?!\4))

https://regex101.com/r/D0lTUF/1

扩展

 (?:
      (?<=
           \b 
           ( )                           # (1)
           (?=
                ( [a-z] )                     # (2)
           )
      )
      \2 
      (?! \2 )
   |  
      (?<=
           ( [a-z] )                     # (3)
           (?! \3 )
           (?=
                ( [a-z] )                     # (4)
           )
      )
      \4 
      (?! \4 )
 )