正则表达式不会选择中间组

时间:2015-03-22 12:50:20

标签: php regex pcre

(PHP)正则表达式是:

"/\b(screen|front|glass|lcd)\b.*?\b(not)?\b.*?\b(replaced|cracked|broken|chipped)\b/i"

目的是让正则表达式匹配:

"screen is not cracked"
"screen is cracked"

并选择NOT作为第二组。但是,对于上述样本输入,似乎第二组都是空的。

我做错了什么?

提示:我正在使用http://www.regexe.com

对此进行测试

3 个答案:

答案 0 :(得分:3)

因为匹配可选项not的模式之前的.*?也会贪婪地匹配not。在这种情况下,您需要使用否定前瞻。

(screen|front|glass|lcd)(?:(?!\bnot\b).)*(not)?.*?(replaced|cracked|broken|chipped)

(?:(?!\bnot\b).)*将检查要匹配的字符是否不是字符串not中的起始字母。如果是,那么它将匹配以下字符。否则,它将与下列字符不匹配,从而导致空匹配(,因为* )。

DEMO

答案 1 :(得分:1)

您可以将第一个非贪婪量词放在一个带有“not”字样的可选组中:

\b(screen|front|glass|lcd)\b(?:.*?\b(not)\b)?.*?\b(replaced|cracked|broken|chipped)\b

所以\b(not)\b在非捕获组中不再是可选的,而非贪婪量词会使其工作并在达到“未”时停止。

一种优化的方式,懒散地抓住词语直到破解/削减/替换/破坏并最终捕获“不”:

\b(screen|front|glass|lcd)\W+(?>(?:(not)|\w+)\W+)*?(?=[crb])(c(?:racked|hipped)|replaced|broken)\b

答案 2 :(得分:0)

你忘记了“是”这个词

m!\b(screen|front|glass|lcd)\b *is *\b(not\b)?(replaced|cracked|broken|chipped)\b!i