如何否定Java中的任何正则表达式

Way*_*yne 10 java regex regex-negation

我有一个我想要否定的正则表达式,例如

/(.{0,4})
Run Code Online (Sandbox Code Playgroud)

哪个String.matches返回以下内容

"/1234" true
"/12" true
"/" true
"" false
"1234" false
"/12345" false
Run Code Online (Sandbox Code Playgroud)

有没有办法否定(仅使用regx)以上结果,以便结果是:

"/1234" false
"/12" false
"/" false
"" true
"1234" true
"/12345" true
Run Code Online (Sandbox Code Playgroud)

我正在寻找一种适用于任何regx的通用解决方案,而无需重写整个正则表达式.

我看过以下 如何否定整个正则表达式?使用(?!pattern),但这对我来说似乎不起作用.

以下regx

(?!/(.{0,4}))
Run Code Online (Sandbox Code Playgroud)

返回以下内容:

"/1234" false
"/12" false
"/" false
"" true
"1234" false
"/12345" false
Run Code Online (Sandbox Code Playgroud)

这不是我想要的.任何帮助,将不胜感激.

Ala*_*ore 28

你需要添加锚点.原始正则表达式(减去不需要的括号):

/.{0,4}
Run Code Online (Sandbox Code Playgroud)

...匹配一个包含斜杠的字符串,后跟零到四个字符.但是,因为你正在使用matches()它自动锚定的方法,就好像它是真的:

^/.{0,4}$
Run Code Online (Sandbox Code Playgroud)

为了达到相反的目的,你不能依靠自动锚定; 你必须至少在前瞻中明确表示结束锚.您还必须使用a"填充"正则表达式,.*因为matches()要求正则表达式使用整个字符串:

(?!/.{0,4}$).*
Run Code Online (Sandbox Code Playgroud)

但我建议您明确锚定整个正则表达式,如下所示:

^(?!/.{0,4}$).*$
Run Code Online (Sandbox Code Playgroud)

它没有任何害处,它使你的意图非常清楚,特别是对于那些从Perl或JavaScript等其他版本学习正则表达式的人.该matches()方法的自动锚定非常不寻常.


daj*_*vax 9

我知道这是一个非常古老的问题,但希望我的答案可以帮助任何将来寻找这个问题的人。

艾伦摩尔的回答几乎是正确的。您还需要对整个正则表达式进行分组,否则您将面临仅锚定原始正则表达式的一部分的风险。

例如,如果您想否定以下正则表达式:(abc|def匹配"abc""def"

前置(?!和附加$).*。你最终会得到(?!abc|def$).*.

这里的锚仅适用于def,这意味着"abcx"在应该匹配时不会匹配。

我宁愿前置(?!(?:和附加)$).*.

String negateRegex(String regex) {
    return "(?!(?:" + regex + ")$).*";
}
Run Code Online (Sandbox Code Playgroud)

从我的测试看来,它negateRegex(negateRegex(regex))在功能上确实与regex.