Variable length look-behind

纵然是瞬间 提交于 2019-11-27 17:53:47

问题


Is there any elegant solution to build a variable length look-behind regex such as this one ?

/(?<=eat_(apple|pear|orange)_)today|yesterday/g;

It seems Perl has a very impressive regex engine and variable length lookbehind would be very interesting. Is there a way to make it work or should I forget this bad idea ?


回答1:


Use \K as a special case.

It's a variable length positive lookbehind assertion:

/eat_(?:apple|pear|orange)_\Ktoday|yesterday/g

Alternatively, you can list out your lookbehind assertions separately:

/(?:(?<=eat_apple_)|(?<=eat_pear_)|(?<=eat_orange_))today|yesterday/g

However, I would propose that it's going to be a rare problem that could potentially use that feature, but couldn't be rethought to use a combination of other more common regex features.

In other words, if you get stuck on a specific problem, feel free to share it here, and I'm sure someone can come up with a different (perhaps better) approach.




回答2:


How about:

(?:(?<=eat_apple_)|(?<=eat_pear_)|(?<=eat_orange_))(today|yesterday)

A little bit uggly, but it works.




回答3:


You can use look-ahead instead of look-behind:

/(?:eat_(apple|pear|orange)_)(?=today|yesterday)/g

and in general, there is an alternative way to describe things that naively seem to require look-behind.




回答4:


Blog post found today, linked to me at #regex @ irc.freenode.org:

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

This article explains how to do a variable width look-behind in PCRE.

The solution would then be:

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

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



来源:https://stackoverflow.com/questions/25563891/variable-length-look-behind

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!