我有一个正则表达式,我想求反,例如
/(.{0,4})
字符串。匹配返回以下
"/1234" true
"/12" true
"/" true
"" false
"1234" false
"/12345" false
是否有一种方法可以对上面的结果取反(仅使用regx),从而使结果为:
"/1234" false
"/12" false
"/" false
"" true
"1234" true
"/12345" true
我正在寻找一个通用的解决方案,将适用于任何正则表达式,而无需重写整个正则表达式。
我看了以下内容如何对整个正则表达式求反?使用(? !模式),但这似乎不适合我。
下面的regx
(?!/(.{0,4}))
返回以下内容:
"/1234" false
"/12" false
"/" false
"" true
"1234" false
"/12345" false
这不是我想要的。
您需要添加锚。原始正则表达式(减去不必要的括号):
/.{0,4}
…匹配包含斜杠后再加0到4个字符的字符串。但是,因为你使用的是matches()
方法,它是自动锚定的,就好像它真的是:
^/.{0,4}$
要达到相反的效果,你不能依赖于自动锚定;您必须至少在前瞻性中显式地设置结束锚。您还必须用.*
"填充"正则表达式,因为matches()
要求正则表达式消耗整个字符串:
(?!/.{0,4}$).*
但是我建议你显式地锚定整个正则表达式,像这样:
^(?!/.{0,4}$).*$
它没有害处,它使您的意图非常清楚,特别是对于那些从其他风格(如Perl或JavaScript)学习正则表达式的人。matches()
方法的自动锚定是非常不寻常的。
我知道这是一个非常古老的问题,但希望我的答案可以帮助任何人在未来寻找这个
而Alan Moore的答案几乎是正确的。您还需要对整个正则表达式进行分组,否则您可能只锚定了原始正则表达式的一部分。
例如,如果您想对以下正则表达式求反:abc|def
(匹配"abc"
或"def"
前置(?!
和追加$).*
。你最终会得到(?!abc|def$).*
。
这里的锚只适用于def
,这意味着"abcx"
在应该匹配时将不匹配。
我宁愿在(?!(?:
前加上)$).*
。
String negateRegex(String regex) {
return "(?!(?:" + regex + ")$).*";
}
从我的测试来看,negateRegex(negateRegex(regex))
在功能上确实与regex
相同。
假设我们的正则表达式是MYREG,用:
^(?:(?!.*MYREG).*)$