带有“非字符”的 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。
(?<=(?<!\\)(?:\\2)*\+)
后视要求紧靠左侧的 +
前面没有紧跟 \
,然后是任意数量的双反斜杠。
【讨论】:
哇,这么好的修正,非常感谢。我不明白 (?:\\2) 是做什么的,但我确信通过一些谷歌搜索我可以轻松搞定。 @Pakoco(?:\\2)*
是一个匹配两个反斜杠零次或多次的non-capturing group。请注意,您可以使用一个环视和一个捕获组来实现您想要的:(?<!\\)(?:\\2)*\+((?:%?[fFsmhd])+)
。 text you need 在第 1 组中。以上是关于带有“非字符”的 Lookbehind 忽略位置 0 的匹配的主要内容,如果未能解决你的问题,请参考以下文章
如何使用负前瞻(NOT lookbehind)来匹配在特定位置不包含给定子字符串的字符串?