java - 正则表达式匹配中的意外结果

时间:2017-02-27 14:18:30

标签: java regex

我试图检查每一行是否等于" test"。当我尝试运行以下代码时,我希望结果为真,因为每一行都是" test"。然而,结果是错误的。

// Expected outcome:
// "test\ntest\ntest" - should match
// "test\nfoo\ntest" - should not match
// "test\ntesttest\ntest" - should not match

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

System.out.println(matcher.matches()); // result is false

我在这里缺少什么?为什么结果是假的?

3 个答案:

答案 0 :(得分:2)

由于您正在使用"",因此它与整个字符串Pattern.MULTILINE匹配。但是在正则表达式中,您指定字符串应该只包含test\ntest的单个实例,因为它被开始和结束锚点包围。

答案 1 :(得分:1)

使用Pattern.compile("^test$", Pattern.MULTILINE),您只要求正则表达式引擎将一行匹配为test。使用Matcher#matches()时,您告诉正则表达式引擎匹配完整字符串。由于您的字符串不等于test,因此您将得到false

要验证包含全部等于test的行的字符串,您可以使用

Pattern.compile("^test(?:\\Rtest)*$")

在较旧的Java版本中,您需要将\R(任何换行符)替换为\n\r?\n

请参阅online demo

Pattern pattern = Pattern.compile("^test(?:\\Rtest)*$");
Matcher matcher = pattern.matcher("test\ntest");
System.out.println(matcher.matches()); // => true

答案 2 :(得分:0)

Pattern.MULTILINE允许您的正则表达式在行分隔符之前和之后匹配^$,这不是默认行为。默认值仅匹配输入的开头和结尾。

但是,如果使用matches(),它会尝试将正则表达式与整个输入文本匹配,从而产生false,因为输入不等于"test"

虽然matches()不起作用,但您可以使用find()查找与正则表达式匹配的输入的子序列。由于^$\n之前和之后匹配,因此您的模式会找到两个子序列。

但那只是我的两分钱。

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

System.out.println(matcher.matches()); // prints "false", the whole input doesn't match a single "test"

System.out.println(matcher.find());    // prints "true"
System.out.println(matcher.group());   // prints "test"

System.out.println(matcher.find());    // prints "true"
System.out.println(matcher.group());   // prints "test"

System.out.println(matcher.find());    // prints "false"