我支持这个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处理这种情况的原因,我真的很感激.
您将空字符串传递给匹配器。对于Pattern.MULTILINE,^预计 会在字符串的开头匹配,但在 Java 中可能有点不同:
如果
MULTILINE模式被激活,则^在 input 的开头和任何行终止符之后匹配,除了 input 的末尾。
由于字符串为空,因此输入的开头就是其结尾。
注意:如果默认传递该标志,但实际上您希望模式在字符串的开头匹配,则可以使用\A代替^和\z作为字符串的结尾,而不是$使用 ( 来匹配字符串的开始/结束Pattern.MULTILINE)即使是空字符串也会通过测试\\A\\s*\\z)。