正则expression式的可变长度lookbehind-assertion选项

在Python / PHP / JavaScript中是否有正则expression式的实现支持可变长度lookbehind-assertion?

/(?<!foo.*)bar/ 

我怎样才能写一个具有相同含义的正则expression式,但不使用lookbehind-assertion?

这种断言是否有可能在某一天实施?

我觉得事情好多了。

更新:

(1)已经有支持变长lookbehind-assertion的正则expression式实现。

Python模块的正则expression式 (不是标准的,但额外的regex模块)支持这样的断言(并有许多其他很酷的function)。

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

对于我来说,有一些正则expression式是Perl无法做到的,而Python可以做到这一点,这真是一个非常大的惊喜。 也许,Perl的“增强的正则expression式”的实现呢?

(感谢和+1对MRAB)。

(2)现代正则expression式中有一个很酷的function\K

这个符号意味着当你进行replace时(从我的观点来看,最有趣的断言使用情况就是replace),在\K之前find的所有字符都不能被改变。

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

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

更多关于\K

  • Perl Regular Expression \ K Trick
  • PCRE Regex Spotlight:\ K

据我所知,你不能在同一个正则expression式中使用\ K两次。 而且你不能说出你想要“杀死”你find的angular色的点。 这总是一直到行的开始。

(感谢和ikegami + 1)。

我的其他问题:

  • 是否有可能说出什么点必须是最终的效果?
  • 那么为Perl / Ruby / JavaScript / PHP增强正则expression式实现呢? 就像Python的regex

大多数情况下,通过使用\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 

对于Python,有一个正则expression式的实现支持可变长度的lookbehinds:

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

它被devise成与标准的重新模块向后兼容。

您可以反转string与模式,并使用可变长度的前瞻

(rab(?!\w*oof)\w*)

粗体匹配:

raboof rab7790oof raboo rabof rab rabo raboooof rabo

据我所知原始解决scheme:

Jeff'japhy'Pinyan

你显示的正则expression式会发现没有前面有foobar任何实例。

一个简单的select是首先将foo与string进行匹配,并find第一个匹配的索引。 然后searchbar ,并查看是否可以find该索引之前的事件。

如果你想find不是直接foo前面的bar实例,我也可以为它提供一个正则expression式(不使用lookbehind),但是它会非常难看。 基本上,反转/foo//[^f]oo|[^o]o|[^o]|$/

 foo.*|(bar) 

如果foo先在string中,那么正则expression式将匹配,但是不会有组。

否则,它会findbar并将其分配给一个组。

所以你可以使用这个正则expression式,并在find的组中find你的结果:

 >>> import re >>> m = re.search('foo.*|(bar)', 'f00bar') >>> if m: print(m.group(1)) bar >>> m = re.search('foo.*|(bar)', 'foobar') >>> if m: print(m.group(1)) None >>> m = re.search('foo.*|(bar)', 'fobas') >>> if m: print(m.group(1)) >>> 

资源。