我有一个我想要否定的正则表达式,例如
/(.{0,4})
String.matches返回以下内容
"/1234" true
"/12" true
"/" true
"" false
"1234" false
"/12345" false
有没有办法否定(仅使用regx)以上结果:
"/1234" false
"/12" false
"/" false
"" true
"1234" true
"/12345" true
我正在寻找一种适用于任何regx的通用解决方案,而无需重写整个正则表达式。
我看过以下内容 How to negate the whole regex?使用(?!pattern),但这对我来说似乎不起作用。
以下regx
(?!/(.{0,4}))
返回以下内容:
"/1234" false
"/12" false
"/" false
"" true
"1234" false
"/12345" false
这不是我想要的。 任何帮助将不胜感激。
答案 0 :(得分:27)
您需要添加锚点。原始正则表达式(减去不需要的括号):
/.{0,4}
...匹配包含斜杠的字符串,后跟0到4个字符。但是,因为你正在使用matches()
方法,它会自动锚定,就像它真的一样:
^/.{0,4}$
为了达到相反的目的,你不能依靠自动锚定;你必须至少在前瞻中明确表示结束锚。您还必须使用.*
“填充”正则表达式,因为matches()
要求正则表达式使用整个字符串:
(?!/.{0,4}$).*
但我建议您明确地锚定整个正则表达式,如下所示:
^(?!/.{0,4}$).*$
它没有任何害处,它使您的意图非常清晰,特别是对于那些从Perl或JavaScript等其他版本学习正则表达式的人。 matches()
方法的自动锚定非常不寻常。
答案 1 :(得分:1)
我知道这是一个非常老的问题,但希望我的回答可以帮助将来寻找此问题的任何人。
Alan Moore的答案几乎是正确的。您也需要将整个正则表达式分组,否则可能会锚定原始正则表达式的一部分。
例如,如果要否定以下正则表达式:abc|def
(与"abc"
或"def"
匹配
添加(?!
和添加$).*
。您将以(?!abc|def$).*
结尾。
此处的锚点仅适用于def
,这意味着"abcx"
在应该匹配时将不匹配。
我宁愿在(?!(?:
之前加上)$).*
。
String negateRegex(String regex) {
return "(?!(?:" + regex + ")$).*";
}
根据我的测试,看起来negateRegex(negateRegex(regex))
的功能确实与regex
相同。