为什么^\s*$与MULTILINE不匹配?"

shm*_*mee 5 java regex

我支持这个Java应用程序,其中开发人员基于RegEx实现了一些过滤.为了尽可能通用,他们使用MULTILINE标志编译模式.

前几天我发现了一些意外的事情.在Java中,模式与MULTILINE标志"^\\s*$"不匹配"".它没有那个标志就匹配了.

Pattern pattern = Pattern.compile("^\\s*$", Pattern.MULTILINE);
Matcher matcher = pattern.matcher("");

System.out.println("Multiline: "+matcher.find());

pattern = Pattern.compile("^\\s*$");
matcher = pattern.matcher("");

System.out.println("No-multiline: "+matcher.find());
Run Code Online (Sandbox Code Playgroud)

这会产生以下输出

Multiline: false
Non-Multiline: true
Run Code Online (Sandbox Code Playgroud)

可以看到相同的结果matches():

System.out.println("Multiline: " + ("".matches("(?m)^\\s*$")));
System.out.println("No-multiline: " + ("".matches("^\\s*$")));
Run Code Online (Sandbox Code Playgroud)

我希望所有案例都能匹配.
在Python中,情况就是这样.这个:

import re

print(re.search(r'^\s*$', "", re.MULTILINE))
print(re.search(r'^\s*$', ""))
Run Code Online (Sandbox Code Playgroud)

得到:

<_sre.SRE_Match object; span=(0, 0), match=''>
<_sre.SRE_Match object; span=(0, 0), match=''>
Run Code Online (Sandbox Code Playgroud)

在Perl中,两个案例都匹配,我想我记得它与PHP相同.

如果有人能解释Java处理这种情况的原因,我真的很感激.

Wik*_*żew 3

您将空字符串传递给匹配器。对于Pattern.MULTILINE^预计 会在字符串的开头匹配,但在 Java 中可能有点不同:

如果MULTILINE模式被激活,则^在 input 的开头和任何行终止符之后匹配,除了 input 的末尾

由于字符串为空,因此输入的开头就是其结尾。

注意:如果默认传递该标志,但实际上您希望模式在字符串的开头匹配,则可以使用\A代替^\z作为字符串的结尾,而不是$使用 ( 来匹配字符串的开始/结束Pattern.MULTILINE)即使是空字符串也会通过测试\\A\\s*\\z)。

  • 我理解文档的方式是“^”总是在字符串的开头匹配,并且如果在实际上为空的行开头和字符串末尾有一个行终止符,则例外情况适用。感谢您提示使用“\\A”和“\\z”代替。 (2认同)