正则表达式处理零长度匹配

时间:2015-01-26 15:30:43

标签: java regex regex-negation regex-lookarounds

我有带*(星号)符号的字符串作为输入。如果字符串有两个连续的星号,则认为该字符串无效。但是,有一个转义符号\(反斜杠)。

例如:

  • " **" (无效)
  • " \ **" (有效)
  • "壳体**" (无效)
  • "壳体\ **" (有效)
  • " * \ *" (有效)

我坚持使用这样的正则表达式会产生错误的结果:

  1. /[^\\]\*\*/ - java.util.regex.Pattern.compile("/[^\\\\]\\*\\*/")
  2. /([^\\]*?\*\*)|(\*\*)/ - java.util.regex.Pattern.compile("/([^\\\\]*?\\*\\*)|(\\*\\*)/")
  3. 此外,我已经从这里了解了贪婪,不情愿和占有欲的量化http://docs.oracle.com/javase/tutorial/essential/regex/quant.html

    我知道问题是关于零长度匹配,但无法生成正确的正则表达式。

2 个答案:

答案 0 :(得分:2)

使用string.matches方法。对于有效字符串,它返回true。

String s1 = "case**";
String s2 = "case\\**";
System.out.println(s1.matches("(?=.*(\\\\\\*\\*|\\*\\\\\\*)).*"));
System.out.println(s2.matches("(?=.*(\\\\\\*\\*|\\*\\\\\\*)).*"));

输出:

false
true

DEMO

答案 1 :(得分:1)

你在寻找一个只能匹配无效字符串的正则表达式吗?这应该做:

"(?<!\\\\)\\*\\*+"

它将连续匹配两个或多个星号,而不是反斜杠。

编辑:(?<!foo)东西被称为&#34;负面观察&#34;。它匹配字符串中的任何零长度位置,该位置不会紧跟在括号内的正则表达式匹配的区域之前(&#34; foo&#34;在这种情况下,或者在您的反斜杠中)。 我首先将其设为[^\\\\],这几乎是相同的(在这种情况下),除了它匹配任何字符,而不是反斜杠,但不是字符的 absense ,例如在&#34; **&#34;中的字符串的开头。

有一个很好的详细描述,包括外观(后视和前瞻)以及许多其他正则表达式&#34;魔法&#34; here