我刚刚观察到这种行为;
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 */
这是什么?我怎么理解这个?我希望有人可以对此有所了解,真的很感激。
答案 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中进行测试,一切都按预期工作:
/^$/