繁体   English   中英

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

[英]Regular expression doesn't match empty string in multiline mode (Java)

我刚观察到这种行为;

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 */

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

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

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

if ( "" =~ /^$/m   ) { print "/^\$/m    matches\n"; }
if ( "" =~ /^$/    ) { print "/^\$/     matches\n"; }
if ( "" =~ /\A\Z/m ) { print "/\\A\\Z/m  matches\n"; }
if ( "" =~ /\A\Z/  ) { print "/\\A\\Z/   matches\n"; }
if ( "" =~ /\A\z/  ) { print "/\\A\\z/   matches\n"; }
if ( "" =~ /^/m    ) { print "/^/m     matches\n"; }
if ( "" =~ /$/m    ) { print "/\$/m     matches\n"; }


__END__


/^$/m    matches
/^$/     matches
/\A\Z/m  matches
/\A\Z/   matches
/\A\z/   matches
/^/m     matches
/$/m     matches

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM