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

2022-09-03 07:31:59

我刚刚观察到这种行为;

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

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

默认情况下,正则表达式 ^ 和 $ 忽略行终止符,并且仅在整个输入序列的开头和结尾分别匹配。如果激活了多行模式,则 ^ 在输入的开头和任何行终止符之后(输入末尾除外)匹配。当在多行模式下时,$ 匹配正好在行终止符或输入序列的末尾之前。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 */

那么这是什么呢?我如何理解这一点?我希望有人能对此有所了解,将不胜感激。


答案 1

如果激活了多行模式,则 ^ 在输入的开头和任何行终止符之后(输入末尾除外)匹配。

由于您处于输入的末尾,因此无法在多行模式下匹配。^

这是令人惊讶的,甚至是令人作呕的,但根据其文档。


答案 2

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

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

所以你在m2中有一行,它是空的OR只包含尾线的字符,没有其他字符。因此,为了与给定的行相对应,您的模式应该只有“$”,即:

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