是否可以在正则表达式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个捕获组”表达式,并且没有等效替代项,那么我将不得不寻找另一种策略。
答案 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 )
)