具有负前瞻性的正则表达式忽略单词“class”

时间:2012-09-19 15:51:27

标签: php regex preg-replace negative-lookahead

我对此感到疯狂,这很简单,但我无法弄清楚正确的正则表达式。我需要一个匹配黑名单的正则表达式,即“屁股”。

例如,在此字符串中:

<span class="bob">Blacklisted word was here</span>bass

我试过那个正则表达式:

((?!class)ass)

匹配“bass”中的“ass”而不是“class”。 这个正则表达式在两个出现时标记“屁股”。我检查了谷歌上的多个负面前瞻,但都没有。

注意:这适用于CMS,主持人可以轻松找到可能不好的字词,我知道您不能依赖计算机进行过滤。

3 个答案:

答案 0 :(得分:4)

如果你有lookbehind可用(其中,IIRC,JavaScript没有,这似乎很可能你正在使用它)(只是注意到PHP标签;你可能有lookbehind可用),这是非常微不足道的:

(?<!cl)(ass)

没有后卫,你可能需要做这样的事情:

(?:(?!cl)..|^.?)(ass)

那是ass,只要它们不是cl,就会有任意两个字符,或者{0}}在行开头之后为零或一个字符。

请注意,这可能不是实施黑名单的最佳方式。你可能想要这个:

ass

哪个匹配单词\bass\b ,但不包含任何包含ass的单词(如assassociation或其他任何内容)。

答案 1 :(得分:2)

在我看来,你实际上是在尝试使用两个列表:一个用于应该排除的单词(即使一个是其他单词的一部分),另一个用于根本不应该更改的单词 - 即使他们将第一个列表中的单词作为子串。

这里的诀窍是知道在哪里使用lookbehind:

/ass(?<!class)/

换句话说,好看的负面后视应该跟随坏词模式,而不是在它之前。然后它会正常工作。

你甚至可以连续获得其中一些:

/ass(?<!class)(?<!pass)(?<!bass)/

但是,这会匹配passholepass。为了使其更加防弹,我们可以添加检查单词边界:

/ass(?<!\bclass\b)(?<!\bpass\b)(?<!\bbass\b)/

更新:当然,使用(?<!cl)(?<!b)等检查字符串的部分效率更高。但我的观点是你仍然可以在正则表达式中使用白名单中的全部单词。

然后,也许相应地准备白名单是明智的(因此必须检查更短的模式)。

答案 2 :(得分:-1)

这个是你想要的吗? (?<!class)(\w+ass)