一尘不染

正则表达式的变长后置断言替代

javascript

在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的增强型正则表达式实现如何?类似于regexPython。

阅读 435

收藏
2020-05-01

共1个答案

一尘不染

在大多数情况下,您可以使用来避免变长后视\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
2020-05-01