我正在尝试以下模式:
Pattern p = Pattern.compile("^(\\d+)$");
奇怪的是,恕我直言:
p.matcher("123\n").find() == true;
p.matcher("123\n").lookingAt() == true; // also weird
p.matcher("123\n\n").find() == false; // ok
p.matcher("123\na").find() == false; // also ok
p.matcher("123\n").matches() == false; // ok to me
在Javadocs中引用文档“ multiline flag”:
启用多行模式。 在多行模式下,表达式^和$分别在行终止符或输入序列的结尾之后或之前匹配。默认情况下,这些表达式仅在整个输入序列的开头和结尾匹配。
对我来说,'\ n'(即换行符)不是输入序列的结尾,因此'$'仅应在多行模式下与之匹配。
我是否缺少某些东西,或者这是Java中的错误?另外,如果您尝试相同的模式并在Javascript中测试字符串,则会看到Javascript的行为正确:
/^(\d+)$/.test("123\n") == false
/^(\d+)$/.exec("123\n") == null
(顺便说一下,我正在RHEL 7.2上使用Java 8)
谢谢!
答案 0 :(得分:0)
EOL取决于操作系统。
尝试将测试模式更改为“ 123” + System.lineSeparator()
答案 1 :(得分:-1)
在多行模式下,表达式^
和$
与以下之一匹配:
默认情况下,这些表达式仅在整个输入序列的开头和结尾匹配。
我可以在这里看到两个单独的问题:
Matcher#find
成功。 Matcher#lookingAt
与Matcher#matches
类似,因为它总是始于该区域的开头;但与此不同的是,它不需要整个区域都匹配。这意味着以下两个都将显示true
:
System.out.println(p.matcher("123\n").find());
System.out.println(p.matcher("123\n").lookingAt());
您尚未在代码中应用多行切换。为了应用此开关,您需要将Pattern.MULTILINE
作为第二个参数传递给Pattern#compile
。应用此开关后,以下两项也将按照上述说明显示true
:
System.out.println(p.matcher("123\n\n").find());
System.out.println(p.matcher("123\na").find());
由于缺少多行模式,因此这些表达式仅在整个输入序列的开头和结尾匹配,如果未应用多行模式,它们将返回false
演示:
import java.util.regex.Pattern;
public class Main {
public static void main(String[] args) {
Pattern p = Pattern.compile("^(\\d+)$", Pattern.MULTILINE);
System.out.println(p.matcher("123\n").find());
System.out.println(p.matcher("123\n").lookingAt());
System.out.println(p.matcher("123\n\n").find());
System.out.println(p.matcher("123\na").find());
System.out.println(p.matcher("123\n").matches());
}
}
输出:
true
true
true
true
false