同一个正则表达式中的两个贪婪量词

Two greedy quantifiers in the same regex

如果我有一个结构未知的字符串:

"stuff I don't care about THING different stuff I don't care about THING ... THING even more stuff I don't care about THING stuff I care about"

我想捕获 "stuff I care about",它总是在最后一次出现 THING 之后。 THING 有可能出现 0 次或多次。如果出现 0 次,那么就没有我关心的东西。字符串不能以 THING 开头或结尾。

一些可能的字符串:

"stuff I don't care about THING stuff I care about"

"stuff I don't care about"

一些不可能的字符串:

"THING stuff I care about"

"stuff I don't care about THING stuff I don't care about THING"


我目前对这个问题的解决方案是使用带有两个贪婪量词的正则表达式,如下所示:

if( /.*THING(.*)/ ) {
    $myStuff = ;
}

它似乎有效,但我的问题是这两个贪婪量词将如何相互作用。第一个(最左边的)贪婪量词是否总是 "more greedy" 比第二个?

基本上我保证不会像下面这样分裂:

"stuff I don't care about THING"

= "different stuff I don't care about THING even more stuff I don't care about THING stuff I care about"

与我想要的拆分相比:

"stuff I don't care about THING different stuff I don't care about THING even more stuff I don't care about THING"

"stuff I care about"

正则表达式 returns 最长的最左边匹配项。第一个通配符最初将匹配到行尾,然后一次连续回溯一个字符,直到正则表达式的其余部分产生匹配,即匹配字符串中的最后一个 THING

这是我的看法。

/^(?!THING).+THING((?:(?!THING).)+)$/

接受包含 1 次或多次 THING 的字符串。 THING 不能位于字符串的开头或结尾。它在最后一次 THING 出现后获取文本。

编辑: 在字符串的开头添加了对 'THING' 的检查。

编辑:哇,重读你的规格(我真的误读了)。你说 如果出现 0 次,那么就没有我关心的东西。字符串不能以 THING 开头或结尾。

那么你的正则表达式没问题。 tripleee 很好地说明了情况。

在匹配过程中,.*THING 最初会匹配所有内容,包括 最后一次 出现的 THING

如果模式的其余部分无法匹配,它将回溯变短,并匹配所有内容直到并包括 最后一个 出现的 THING,然后再次尝试其余的模式

但是模式的其余部分是 .*,它将始终匹配,因为它将匹配空字符串

因此,.*THING(.*) 将匹配并包括 last 出现的 THING,并将匹配并捕获字符串的其余部分

注意 . 将匹配除换行符之外的任何内容。如果您的文本中可能有换行符,那么您将需要使用 /s 修饰符来使其完全匹配任何内容

还要注意,如果模式无法匹配(因为,比方说,字符串中没有 THING ) 那么 </code> 将保持不变。它仍将包含最近成功的模式匹配设置的任何内容。这意味着您 <em> 必须 </em> 在使用 <code>

的值之前检查模式匹配的状态