正则表达式与多行模式中的空字符串不匹配(Java)

时间:2012-01-17 14:21:27

标签: java regex

我刚刚观察到这种行为;

Pattern p1 = Pattern.compile("^$");
Matcher m1 = p1.matcher("");
System.out.println(m1.matches()); /* true */

Pattern p2 = Pattern.compile("^$", Pattern.MULTILINE);
Matcher m2 = p2.matcher("");
System.out.println(m2.matches()); /* false */

令我感到奇怪的是,最后一句话是错误的。这就是文档所说的;

  

默认情况下,正则表达式^和$忽略行终止符,并且仅分别匹配整个输入序列的开头和结尾。如果激活MULTILINE模式,则^在输入开始时和任何行终止符之后匹配,但输入结束时除外。当处于MULTILINE模式时,$匹配行终止符或输入序列的结尾。 http://docs.oracle.com/javase/1.4.2...

从我得到的,它应该匹配?以下使事情变得更加混乱;

Pattern p3 = Pattern.compile("^test$");
Matcher m3 = p3.matcher("test");
System.out.println(m3.matches()); /* true */

Pattern p4 = Pattern.compile("^test$", Pattern.MULTILINE);
Matcher m4 = p4.matcher("test");
System.out.println(m4.matches()); /* true */

这是什么?我怎么理解这个?我希望有人可以对此有所了解,真的很感激。

3 个答案:

答案 0 :(得分:7)

  

如果激活MULTILINE模式,则^在开头匹配   输入和任何行终止符之后,输入结束时除外。

由于您在输入结束时,^无法在多线模式下匹配。

这令人惊讶,甚至令人作呕,但仍然根据其文件。

答案 1 :(得分:2)

让我们看看你的第二个例子:

Pattern p2 = Pattern.compile("^$", Pattern.MULTILINE);
Matcher m2 = p2.matcher("");
System.out.println(m2.matches()); /* false */

所以你有一条m2的行,它是空的或只包含结束的字符而没有其他字符。因此,为了对应于给定的行,您的模式应该只是“$”,即:

// Your example
Pattern p2 = Pattern.compile("^$", Pattern.MULTILINE);
Matcher m2 = p2.matcher("");
System.out.println(m2.matches()); /* false */

// Let's check if it is start of the line
p2 = Pattern.compile("^", Pattern.MULTILINE);
m2 = p2.matcher("");
System.out.println(m2.matches()); /* false */

// Let's check if it is end of the line
p2 = Pattern.compile("$", Pattern.MULTILINE);
m2 = p2.matcher("");
System.out.println(m2.matches()); /* true */

答案 2 :(得分:1)

听起来像个臭虫。最多,在多线模式下," ^"和" $"可以解释为在内部边界处匹配。 Java可能没有像Perl那样的扩展变量状态结构。我不知道这是否是一个原因。

/^test$/m匹配的事实证明^ $在多行模式下工作,除非字符串为空(在Java中),但显然空字符串的多行模式测试是荒谬的,因为{{1}为此工作。

在Perl中进行测试,一切都按预期工作:

/^$/