可变长度的后视镜

now*_*wox 15 regex perl

是否有任何优雅的解决方案来构建可变长度的后视正则表达式,例如这个?

/(?<=eat_(apple|pear|orange)_)today|yesterday/g;
Run Code Online (Sandbox Code Playgroud)

似乎Perl有一个非常令人印象深刻的正则表达式引擎和可变长度lookbehind将是非常有趣的.有没有办法使它工作或我应该忘记这个坏主意?

Mil*_*ler 17

使用\K作为一个特例.

这是一个可变长度的正向后观断言:

/eat_(?:apple|pear|orange)_\Ktoday|yesterday/g
Run Code Online (Sandbox Code Playgroud)

或者,您可以单独列出您的lookbehind断言:

/(?:(?<=eat_apple_)|(?<=eat_pear_)|(?<=eat_orange_))today|yesterday/g
Run Code Online (Sandbox Code Playgroud)

但是,我认为这将是一个可能使用该功能的罕见问题,但无法重新考虑使用其他更常见的正则表达式功能的组合.

换句话说,如果你遇到一个特定的问题,请随意在这里分享,我相信有人可以想出一个不同的(也许更好的)方法.

  • Nit:`\ K`不是可变长度的后视镜.它意味着"保持",并排除它包含在`$ &`(匹配的字符串)之前的任何内容.也就是说,`\ K`可用于模拟可变长度的正向后视,因此+1. (6认同)

Tot*_*oto 5

怎么样:

(?:(?<=eat_apple_)|(?<=eat_pear_)|(?<=eat_orange_))(today|yesterday)
Run Code Online (Sandbox Code Playgroud)

有点uggly,但它的工作原理.

  • +1对于小型有限列表来说,这绝对是一个很好的解决方法. (2认同)

小智 5

今天发现的博客文章,链接到我的 #regex @ irc.freenode.org:

http://www.drregex.com/2019/02/variable-length-lookbehinds-actually.html

本文解释了如何在 PCRE 中进行可变宽度后向查找。

那么解决方案是:

/(?=(?=(?'a'[\s\S]*))(?'b'eat_(?:apple|pear|orange)_(?=\k'a'\z)|(?<=(?=x^|(?&b))[\s\S])))today|yesterday/g
Run Code Online (Sandbox Code Playgroud)

https://regex101.com/r/9DNpFj/1