我支持这个Java应用程序,其中开发人员基于RegEx实现了一些过滤。为了尽可能通用,他们使用MULTILINE标志编译模式。
前几天我注意到了一些意想不到的事情。
在Java中,模式"^\\s*$"
与""
不匹配MULTILINE标志。没有那个标志就匹配。
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());
这会产生以下输出
Multiline: false
Non-Multiline: true
matches()
可以看到相同的结果:
System.out.println("Multiline: " + ("".matches("(?m)^\\s*$")));
System.out.println("No-multiline: " + ("".matches("^\\s*$")));
我希望所有案例都能匹配 在Python中,情况就是这样。这样:
import re
print(re.search(r'^\s*$', "", re.MULTILINE))
print(re.search(r'^\s*$', ""))
给出:
<_sre.SRE_Match object; span=(0, 0), match=''>
<_sre.SRE_Match object; span=(0, 0), match=''>
在Perl中,两个案例都匹配,我想我记得它对于PHP来说是相同的。
如果有人能够解释Java处理这种情况的原因,我真的很感激。
答案 0 :(得分:3)
将空字符串传递给匹配器。使用Pattern.MULTILINE
时,^
预计会在字符串的开头匹配,但in Java可能会略有不同:
如果
MULTILINE
模式已激活,那么^
会在输入开头和任何行终止符 之后匹配,但输入结束时 除外。
由于字符串为空,因此输入的开头是结束。
注意:如果您默认情况下传递了标记,但事实上,您希望模式在字符串开头处匹配,则可以使用\A
而不是{{1} }和^
用于字符串结尾而不是\z
,它将匹配字符串start / end,即使是$
(甚至空字符串也会通过Pattern.MULTILINE
测试)