正则表达式的变长后置断言替代
在Python / PHP / JavaScript中是否存在支持可变长度lookbehind-assertion的正则表达式实现?
/(?<!foo.*)bar/
如何编写具有相同含义但不使用lookbehind-assertion的正则表达式?
是否有可能在一天之内实现这种断言?
我认为情况要好得多。
(1)已经有一些正则表达式实现支持变长后向断言。
Python模块正则表达式(不是standardre
,而是其他regex
模块)支持此类断言(并具有许多其他很酷的功能)。
>>> import regex>>> m = regex.search('(?<!foo.*)bar', 'f00bar')
>>> print m.group()
bar
>>> m = regex.search('(?<!foo.*)bar', 'foobar')
>>> print m
None
对于我来说,令Perl和Python不能使用的正则表达式感到非常惊讶。也许,Perl也有“增强的正则表达式”实现吗?
(感谢MRAB +1)。
(2)\K
现代正则表达式有一个很酷的功能。
这个符号意味着当您进行替换时(从我的观点来看,断言最有趣的用例是替换),之前找到的所有字符都\K
不得更改。
s/unchanged-part\Kchanged-part/new-part/x
那几乎就像是一个后置断言,但是当然不是那么灵活。
更多关于\K
:
- Perl正则表达式\ K技巧
- PCRE Regex焦点:\ K
据我了解,您不能在同一正则表达式中两次使用\K。而且,直到说到要“杀死”您发现的角色,您都无法说出。那总是一直到行的开始。
(感谢ikegami +1)。
我的其他问题:
- 能否说出最后一点必须是
\K
效果? - Perl / Ruby / JavaScript / PHP的增强型正则表达式实现如何?类似于
regex
Python。
回答:
在大多数情况下,您可以使用来避免变长后视\K
。
s/(?<=foo.*)bar/moo/s;
将会
s/foo.*\Kbar/moo/s;
负向后看有点棘手。
s/(?<!foo.*)bar/moo/s;
将会
s/^(?:(?!foo).)*\Kbar/moo/s;
因为(?:(?!STRING).)*
是STRING
为[^CHAR]*
是CHAR
。
如果您只是匹配,则可能甚至不需要\K
。
/foo.*bar/s/^(?:(?!foo).)*bar/s
以上是 正则表达式的变长后置断言替代 的全部内容, 来源链接: utcz.com/qa/409461.html