带有“非字符”的 Lookbehind 忽略位置 0 的匹配

Posted

技术标签:

【中文标题】带有“非字符”的 Lookbehind 忽略位置 0 的匹配【英文标题】:Lookbehind with "not character" ignores match at position 0 【发布时间】:2021-08-17 05:07:42 【问题描述】:

我正在尝试实现一个正则表达式来选择 (%?[fFsmhd])1, 前面是 + 而不是 \+

我的第一个选项是(?<=[^\\]\+)(%?[fFsmhd])1,,除了位置 1 永远不匹配之外,它似乎有效。

测试:

+fFsmhd (problem here, does not match)
+fFsmhd (matches)

我发现解决此问题的一种解决方法是将[^\\] 替换为嵌套否定的lookbehind,最终得到这个令人作呕的东西:(?<=(?<!\\)\+)(%?[fFsmhd])1,

测试:

+fFsmhd (matches)
+fFsmhd (matches)

有没有更好的方法来实现这一点而无需嵌套后视来做一个简单的[^\\]

【问题讨论】:

【参考方案1】:

如果没有环视,就不可能做你想做的事。实际上,您的模式有一个缺陷:如果在 + 之前有一个文字 \,它将无法匹配。您需要考虑任意数量的双反斜杠:

(?<=(?<!\\)(?:\\2)*\+)(%?[fFsmhd])+

看到这个.NET regex demo。

(?&lt;=(?&lt;!\\)(?:\\2)*\+) 后视要求紧靠左侧的 + 前面没有紧跟 \,然后是任意数量的双反斜杠。

【讨论】:

哇,这么好的修正,非常感谢。我不明白 (?:\\2) 是做什么的,但我确信通过一些谷歌搜索我可以轻松搞定。 @Pakoco (?:\\2)* 是一个匹配两个反斜杠零次或多次的non-capturing group。请注意,您可以使用一个环视和一个捕获组来实现您想要的:(?&lt;!\\)(?:\\2)*\+((?:%?[fFsmhd])+)。 text you need 在第 1 组中。

以上是关于带有“非字符”的 Lookbehind 忽略位置 0 的匹配的主要内容,如果未能解决你的问题,请参考以下文章

如何使用负前瞻(NOT lookbehind)来匹配在特定位置不包含给定子字符串的字符串?

没有LookBehind功能的正则表达式

正则表达式的可变长度lookbehind-assertion替代方案

非固定长度的lookbehind解决方法

R 正则表达式 Lookbehind

ES2018 新特征之:正则表达式反向(lookbehind)断言