Php 正则表达式不拾取中间组

Php 正则表达式不拾取中间组,php,regex,pcre,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的模式也将贪婪地

(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的模式也将贪婪地匹配
not。对于这种情况,您需要使用负前瞻

(screen|front|glass|lcd)(?:(?!\bnot\b).)*(not)?.*?(replaced|cracked|broken|chipped)
(?:(?!\bnot\b)。*
将检查要匹配的字符是否不是字符串中的起始字母
不是
。如果是,则它将匹配以下字符。否则,它将不匹配以下字符,从而导致空匹配(因为
*


因为匹配可选not的模式之前的
*?
也将贪婪地匹配
not
。对于这种情况,您需要使用负前瞻

(screen|front|glass|lcd)(?:(?!\bnot\b).)*(not)?.*?(replaced|cracked|broken|chipped)
(?:(?!\bnot\b)。*
将检查要匹配的字符是否不是字符串中的起始字母
不是
。如果是,则它将匹配以下字符。否则,它将不匹配以下字符,从而导致空匹配(因为
*

你忘了“是”这个词

你忘了“是”这个词


您可以将第一个非贪婪量词放在一个可选组中,其中包含单词“not”:

因此,
\b(not)\b
在非捕获组中不再是可选的,并且非贪婪量词完成其工作,并在到达“not”时停止

一种优化的方式,它懒散地抓取单词,直到出现裂纹/缺口/替换/损坏,并最终捕获“不”:


您可以将第一个非贪婪量词放在一个可选组中,其中包含单词“not”:

因此,
\b(not)\b
在非捕获组中不再是可选的,并且非贪婪量词完成其工作,并在到达“not”时停止

一种优化的方式,它懒散地抓取单词,直到出现裂纹/缺口/替换/损坏,并最终捕获“不”:


是的,这不是贪婪。因为not是可选的,非贪婪部分也与
not
string.regex101.com匹配,这是一个很棒的站点,我不知道。非常感谢。这是一个很好的答案,但基于效率,我会接受@casimir et hippolyte,这也有效,正则表达式更容易遵循。是的,它不是贪婪的。因为not是可选的,非贪婪部分也与
not
string.regex101.com匹配,这是一个很棒的站点,我不知道。非常感谢。这是一个很好的答案,很有效,但基于效率,我会接受@casimir et hippolyte,这也很有效,正则表达式更容易理解。不,这些只是简单的示例字符串。它应该与“屏幕完美而不开裂”之类的东西相匹配,这就是为什么会出现。*?我真的不知道用户会如何描述屏幕,但我感兴趣的是那些能给我他们所说的要点的关键词。不,这些只是简单的示例字符串。它应该与“屏幕完美而不开裂”之类的东西相匹配,这就是为什么会出现。*?我真的不知道用户会如何描述屏幕,但我感兴趣的是那些能给我他们所说的要点的关键词。
\b(screen|front|glass|lcd)\b(?:.*?\b(not)\b)?.*?\b(replaced|cracked|broken|chipped)\b
\b(screen|front|glass|lcd)\W+(?>(?:(not)|\w+)\W+)*?(?=[crb])(c(?:racked|hipped)|replaced|broken)\b