你能依赖正则表达式语法的解释顺序吗?

时间:2009-12-21 15:58:54

标签: php regex

(这个问题的背景是我认为编写解析维基克里奥尔语标记的东西会很有趣。无论如何,我认为我有解决方案的问题是区分网址中的//和打开/关闭斜体文本的语法)

我的问题有些复杂,所以我试图在标题下分解

如果有一个子串(S1)可以包含由|分隔的一系列子串中的任何一个子串,那么正则表达式解释器只是匹配'S1'中的第一个子串,然后移到正则表达式之后' S1' ?或者在某些情况下可以尝试找到最好/最贪婪的匹配吗?

这是一个尝试让我的问题更清晰的例子: 要搜索的字符串:String
正则表达式:/(?:(Str|Strin).*)/(我的问题中的'S1'指的是非捕获子字符串

我认为上述比赛应该是:
$ 0将是String
$ 1将是Str而不是Strin

这总是会发生或者是实例(例如,'S1'可能使用*贪婪地匹配),其中将使用另一个匹配的子字符串,即我的示例中的Strin

如果上述情况不正确,我应该依赖这种行为吗?

真实世界的例子

/^\/\/(\b((https?|ftp):\/\/|mailto:)([^\s~]*?(?:~(.|$))?)+?(?=\/\/|\s|$)|~(.|$)|[^/]|\/([^/]|$))*\/\//

应该正确匹配:

//Some text including a http//:url//

$ 1 == Some text including a http//:url

注意:我试图使这种相对语言不可知,但我将使用php

2 个答案:

答案 0 :(得分:3)

PHP使用PCRE regex engine。默认情况下,以及PHP使用它的方式,PCRE引擎以最左边的模式运行。此模式返回第一个匹配项,从左到右评估正则表达式。所以是的,你可以依赖PHP解释正则表达式的顺序。

pcre_dfa_exec()函数提供的另一种模式评估所有可能的匹配并返回最长的匹配。

答案 1 :(得分:0)

在PHP中,使用preg扩展,您可以在贪婪和非贪婪的运算符之间进行选择(通常会向它们附加'?')。

顺便提一下,在您提供的示例中,如果您希望Strin匹配,则必须反转您的案例:/(?:(Strin|Str).*)/。我认为,你应该把最通用的表达式放在正则表达式的末尾。

仅供参考,使用preg引擎,

  

交替运算符既不贪婪也不懒惰但是有序

掌握正则表达式,J。Friedl,p175

如果你想要一个贪婪的引擎,你必须使用一个符合Posix的引擎(ereg - 但它已被弃用)。