正则表达式:不包含/不含有模式

3
我有一个正则表达式模式,可以匹配HTML的script标签。我该如何更改这个script标签的模式,以便该模式意味着“输入字符串不匹配”这个script标签模式?
换句话说,给定一个模式,需要做什么修改才能将该模式的含义改为“不匹配该模式”?
例如,如果我有一个模式:\d{3}-\d{3}-\d{4},那么相应的模式是什么,意思是“不匹配\d{3}-\d{3}-\d{4}”?

为什么不简单地使用 somestring!="<script>" - thejh
2
你不能只是使用!来对匹配进行布尔取反吗?例如:!preg_match("\d{3}", $string); - gnarf
1
更改使用该模式的逻辑(例如if !regex.match())可能会更容易,而不是尝试更改模式本身。 - Anon.
1
有时候你可以指定正则表达式,但不能改变代码逻辑,所以需要一个反匹配的正则表达式。 - ericslaw
5个回答

3
您可以使用负向前瞻来否定一个正则表达式模式。但这与简单地否定正则表达式略有不同。在Java(以及许多其他语言)中,负向前瞻看起来像下面这样:
(?!\d{3}-\d{3}-\d{4})

请注意,这并不能完全回答这个问题。使用正则表达式找到正则语言的逆是一项不容易的任务(我认为)。解决这个问题的一个更简单的方法是反转程序逻辑:
而不是:
if (string.matches(yourRegex))

Do:

if (!string.matches(yourRegex))

虽然当然这并不会真正“匹配”一个不是原始匹配的字符串。但我不知道他们想要实现什么。 - El Ronnoco
这并没有完全回答问题,你打算如何使用(?!\d{3}-\d{3}-\d{4})来匹配不包含原始模式的字符串?正则表达式本身只能匹配_123-456-7890_,似乎还缺少一些东西! - Andrew Clark
@安德鲁,我不确定用正则表达式是否可以找到正规语言的逆。我只是建议一个可能的解决方案供你参考。最好的方式是反转代码的逻辑。 - jjnguy
可能有些我忽略的地方,但我认为(?!.*\d{3}-\d{3}-\d{4})是这种情况下一个完整的正则表达式? - Andrew Clark
@jjnguy:实际上,我认为正则表达式的反转也是正则的。这是因为所有的正则语言都可以用正则表达式表示,也可以用有限自动机表示。而且在有限自动机的情况下,如果你只是交换接受状态和非接受状态,那么你就得到了一个完全匹配原始正则语言补集的机器。因为这个新机器仍然是一个有限自动机,它确实描述了一个正则语言!...不过,寻找描述新自动机的正则表达式是棘手的部分。 - Platinum Azure
显示剩余7条评论

1

对于任意模式来说,这并不容易实现。在实践中,通常在周围的代码中做你想要的事情比在模式本身中更容易。例如,不是

grep '\d{3}-\d{3}-\d{4}' file

你可以使用

grep -v '\d{3}-\d{3}-\d{4|' file

或者在程序中,您可以更改类似以下的内容

if (pattern.matches()) {
    foo();
}

转换成类似于这样的东西

if (!pattern.matches()) {
    foo();
}

在一种更冗长的方法中,你需要枚举所有可能匹配的值,而不是不匹配的值。所以,假设你想匹配除了字符串<html>之外的所有内容,你可以像这样编写一个正则表达式:
([^<]|<([^h]|h([^t]|t([^m]|m([^l]|l[^>])))))

读这个正则表达式就像在说:“好的,你可以匹配任何字符,但不包括'<',或者你可以匹配'<',但是之后不能匹配'h'... 或者你可以匹配'h',但是之后不能匹配't'... 以此类推。

它很丑陋,但对于简单的字符串匹配,你可以轻松编写一个递归函数,将任何给定的术语转换为上述模式。


0

我完全同意其他回答中说的,你应该对匹配进行否定测试,但是只使用正则表达式,这应该可以做到你想要的:

(?!.*\d{3}-\d{3}-\d{4})

这是一个负向先行断言,通过在先行断言之外不放置任何字符,正则表达式基本上意味着“对于以任意数量的字符(.*)开头,后跟正则表达式\d{3}-\d{3}-\d{4}的任何字符串都失败”。

0
更容易的方法是直接否定测试,比如...
if (!regex.test(str)) ...

(JavaScript示例)
使用^来否定一个字符类很容易,但是整个正则表达式会变得更加复杂。

0
你使用的是什么编程语言?对于你提出的具体问题,最简单的解决方案是在匹配模式前添加一个否定操作符(通常是"!")。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接