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

新手上路,请多包涵

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

/(.{0,4})

which String.matches 返回以下内容

"/1234" true
"/12" true
"/" true
"" false
"1234" false
"/12345" false

有没有办法对上面的内容进行否定(仅使用 regx),以便结果为:

 "/1234" false
"/12" false
"/" false
"" true
"1234" true
"/12345" true

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

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

以下正则表达式

(?!/(.{0,4}))

返回以下内容:

 "/1234" false
"/12" false
"/" false
"" true
"1234" false
"/12345" false

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

原文由 Wayne 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 601
2 个回答

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

 /.{0,4}

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

 ^/.{0,4}$

要实现相反的效果,您不能依赖自动锚定;您必须至少在前瞻中明确结束锚点。您还必须使用 .* “填充”正则表达式,因为 matches() 要求正则表达式使用整个字符串:

 (?!/.{0,4}$).*

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

 ^(?!/.{0,4}$).*$

它没有害处,而且它使您的意图非常清楚,特别是对于那些从其他风格(如 Perl 或 JavaScript)学习正则表达式的人。 matches() 方法的自动锚定非常不寻常。

原文由 Alan Moore 发布,翻译遵循 CC BY-SA 3.0 许可协议

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

Alan Moore 的回答几乎是正确的。您也需要对整个正则表达式进行分组,否则您可能只锚定原始正则表达式的一部分。

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

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

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

我宁愿在前面添加 --- (?!(?: 并附加 )$).*

 String negateRegex(String regex) {
    return "(?!(?:" + regex + ")$).*";
}

从我的测试来看,它看起来像 negateRegex(negateRegex(regex)) 在功能上确实与 regex 相同。

原文由 dajavax 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题