PCRE匹配单词,但排除匹配单词

时间:2016-12-30 13:06:59

标签: php regex pcre

我尝试使用PCRE正则表达式来匹配以下单词列表:

  1. 以下字符串:

    milk, goatmilk, goat milk, cow milk, watch out for ( milk, eggs), egg, cornstarch
    milk. goatmilk. goat milk. cow milk. watch out for ( milk, eggs). egg. cornstarch
    milk goatmilk goat milk cow milk watch out for ( milk, eggs). egg cornstarch
    

    这将是一个简单的例外,但遗憾的是它无法匹配任何这些词:

    • goatmilk
    • 山羊奶

    在上面的例子中,字符串应该匹配,因为单词:

    但如果字符串不包含任何这些单词,则不应该匹配,即:

    sugar, wheat, goatmilk, goat milk, cornstarch
    

    我试图申请这些但没有任何证据:

    我从上面的资源得到的最接近的正则表达式是:

    \b(?!(?:goatmilk|goat\smilk))(egg|milk)\b
    

    这仍将匹配所有单词牛奶,更糟糕的是它会跳过单词egg,因为单词边界。如果我删除边界这个词,它也会匹配山羊奶..

    我已经考虑过使用两个正则表达式的可能性,一个用于匹配所有单词,另一个用于检查排除单词的匹配单词。然而;如果不是山羊和牛奶之间的空间,这将是完美的,因为山羊部分不会在比赛中。

    如果没有选项可以执行此操作,我将使用PHP在空间上进行爆炸,遍历数组,如果找到匹配项,将检查先前的索引值以查看该组合是否包含单词排除以缓解空间问题。然而;我宁愿不使用它,因为我相信这个选项非常难看:(

1 个答案:

答案 0 :(得分:1)

如果您必须避免返回属于milkgoatmilk的{​​{1}},则可以使用(*SKIP)(*FAIL) regex

goat milk

请参阅regex demo

\bgoat\s*milk\b(*SKIP)(*FAIL)|\b(?:eggs?|milk)\b 分支将与\bgoat\s*milk\b(*SKIP)(*FAIL)goatmilk匹配,并会因这2个PCRE动词而丢弃匹配。 goat milk分支将返回其他\b(?:eggs?|milk)\beggeggs个匹配项。