我刚刚观察到了这种行为;
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 */
这是什么?我该如何理解这一点?我希望有人能对此有所了解,我将不胜感激。
如果MULTILINE模式被激活,则^在输入和在除输入端以外的任何行终止符之后。
由于您处于输入的末尾,^
在多行模式中无法匹配。
这是令人惊讶的,甚至恶心,但根据其文件。
让我们仔细看看第二个例子:
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 */
听起来像个bug。在多行模式下,"^"one_answers"$"最多可以被解释为在内部行边界匹配。Java可能没有像Perl那样扩展可变状态结构。我不知道这是否是一个原因。
事实上,/^test$/m
匹配只是证明^$在多行模式下工作,除非字符串为空(在Java中),但很明显,空字符串的多行模式测试是荒谬的,因为/^$/
适用于此。
在Perl中测试,一切如预期:
if ( "" =~ /^$/m ) { print "/^$/m matchesn"; }
if ( "" =~ /^$/ ) { print "/^$/ matchesn"; }
if ( "" =~ /AZ/m ) { print "/\A\Z/m matchesn"; }
if ( "" =~ /AZ/ ) { print "/\A\Z/ matchesn"; }
if ( "" =~ /Az/ ) { print "/\A\z/ matchesn"; }
if ( "" =~ /^/m ) { print "/^/m matchesn"; }
if ( "" =~ /$/m ) { print "/$/m matchesn"; }
__END__
/^$/m matches
/^$/ matches
/AZ/m matches
/AZ/ matches
/Az/ matches
/^/m matches
/$/m matches