正则表达式的可变长度查找隐藏断言替代项

2022-08-30 10:37:39

在 Python/PHP/JavaScript 中是否有支持可变长度 lookbehind 断言的正则表达式实现?

/(?<!foo.*)bar/

如何编写具有相同含义但不使用 lookbehind 断言的正则表达式?

这种类型的断言是否有可能有一天会实现?

事情比我想象的要好得多。

更新:

(1) 已经有一些正则表达式实现支持可变长度查找隐藏断言。

Python模块正则表达式(不是标准的,而是附加模块)支持这样的断言(并且具有许多其他很酷的功能)。reregex

>>> import regex
>>> m = regex.search('(?<!foo.*)bar', 'f00bar')
>>> print m.group()
bar
>>> m = regex.search('(?<!foo.*)bar', 'foobar')
>>> print m
None

对我来说,这是一个很大的惊喜,因为正则表达式中有一些东西是Perl无法做到的,而Python可以做到的。也许,Perl也有“增强正则表达式”的实现?

(感谢和+1到MRAB)。

(2)现代正则表达式中有一个很酷的功能。\K

这个符号意味着当你进行替换时(从我的角度来看,断言最有趣的用例是替换),之前找到的所有字符都不能被更改。\K

s/unchanged-part\Kchanged-part/new-part/x

这几乎就像一个幕后的断言,但当然不是那么灵活。

更多关于 :\K

据我所知,你不能在同一正则表达式中使用\K两次。你不能说到什么时候你想“杀死”你找到的角色。这总是一直到行的开头。

(感谢和+1到池上)。

我的其他问题:

  • 有没有可能说哪一点一定是最后的效果点?\K
  • Perl/Ruby/JavaScript/PHP 的增强型正则表达式实现怎么样?就像Python一样。regex

答案 1

大多数情况下,您可以使用 来避免可变长度外观。\K

s/(?<=foo.*)bar/moo/s;

s/foo.*\Kbar/moo/s;

直到最后遇到的任何事情都不被视为匹配的一部分(例如,为了替换等目的)\K$&

负面的后视有点棘手。

s/(?<!foo.*)bar/moo/s;

s/^(?:(?!foo).)*\Kbar/moo/s;

因为 is to as to .(?:(?!STRING).)*STRING[^CHAR]*CHAR


如果您只是匹配,则甚至可能不需要 .\K

/foo.*bar/s

/^(?:(?!foo).)*bar/s

答案 2

对于Python,有一个正则表达式实现,它支持可变长度的查找隐藏:

http://pypi.python.org/pypi/regex

它被设计为与标准re模块向后兼容。