如何使用正则表达式匹配不在另一个字符串中的字符串出现?

时间:2010-10-27 23:14:19

标签: php regex

我正在尝试将以下序列中的所有“string”匹配之外的那些@@

as87dio u8u u7o @string@ ou os8 string os u

即。第二次出现应该匹配但不是第一次

有人能给我一个解决方案吗?

3 个答案:

答案 0 :(得分:4)

您可以使用negative lookahead and lookbehind

(?<!@)string(?!@)

修改

注意:根据下面的标记评论,这与@stringstring@不匹配。

答案 1 :(得分:2)

您可以尝试:

(?:[^@])string(?:[^@])

答案 2 :(得分:1)

好的,

如果你想不匹配你把它放在一个字符类(方括号)中的字符,并用^字符开头,否定它,例如[^a]表示任何字符,但小写'a'。

因此,如果您不想签名,后跟字符串,然后是另一个NOT at-sign,那么

[^@]string[^@]

现在,问题是字符类将匹配一个字符,所以在你的例子中我们得到“string”,其中包括前导和尾随空格。所以,还有另一个构造告诉你不要匹配任何东西,那就是在开头用一个?:的parens。 (?: )。所以你用它来包围两端。

(?:[^@])string(?:[^@])

好的,但是现在它在字符串的开头不匹配(令人困惑的是,^字符在字符类之外执行双重任务)或在字符串$的末尾。所以我们必须使用OR字符|来说“给我一个非符号或字符串的开头”,最后“给我一个字符串的非符号OR结尾”,如下所示:

(?:[^@]|^)string(?:[^@]|$)

编辑:负向后和向前预测是一种更简单(和更聪明)的解决方案,但并非所有正则表达式引擎都可用。

现在是一个后续问题。如果你有“收敛”这个词你还想要匹配里面的“字符串”吗?换句话说,“字符串”必须单独成为一个单词吗? (尽管我最初的反应,这可能会变得非常复杂:))