在Java中打破正则表达式中的匹配行边界(Pattern.MULTILINE /(?m))?

时间:2010-04-25 08:34:32

标签: java design-patterns

http://www.exampledepot.com/egs/java.util.regex/Line.html上的例子给了我两次假,但不应该!为什么呢?

CharSequence inputStr = "abc\ndef";
String patternStr = "abc$";

// Compile with multiline enabled
Pattern pattern = Pattern.compile(patternStr, Pattern.MULTILINE);
Matcher matcher = pattern.matcher(inputStr);
boolean matchFound = matcher.find();    // true

// Use an inline modifier to enable multiline mode
matchFound = pattern.matches(".*abc$.*", "abc\r\ndef");     // false
System.out.println(matchFound); // false
matchFound = pattern.matches("(?m).*abc$.*", "abc\r\ndef"); // true
System.out.println(matchFound);// false !!!!!

好吧,如果我再添加一个(?s)它可以工作,但如果没有(?s)它不应该工作吗?过去这种行为是否发生了变化,或者作者是否仅仅检查了这个例子?

2 个答案:

答案 0 :(得分:1)

首先,exampledepot.com是一个非常糟糕的网站:从来没有永远假设在那里找到任何“真相”。

在正则表达式中,$从不与字符匹配,它与位置匹配。在(?m)模式下,它匹配换行符之前的“空字符串”或字符串的结尾。因此,给定字符串"abc\r\ndef",正则表达式".*abc$.*"不匹配,因为正则表达式中不存在\r\n$c\r之间的排名相匹配。

你应该做的是:

System.out.println("abc\r\ndef".matches(".*abc$\r\n.*"));     // false
System.out.println("abc\r\ndef".matches("(?m).*abc$\r\n.*")); // true

答案 1 :(得分:0)

我不熟悉社区维基的工作方式,但如果认为有用,请随意使用此示例。

    System.out.println(
        Pattern.matches("(?m)^abc$\n^def$", "abc\ndef")
    ); // prints "true"

    System.out.println(
        Pattern.matches("(?sm)^abc$.^def$", "abc\ndef")
    ); // prints "true"