开发者

Matching Line Boundaries in a Regular Expression (Pattern.MULTILINE/(?m)) is broken in Java?

The example on ht开发者_Python百科tp://www.exampledepot.com/egs/java.util.regex/Line.html gives false for me twice but should'nt! Why?

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 !!!!!

Well, if I put an additionally (?s) it works, but shouldn't it work without the (?s)? Did this behaviour change in the past or didn't the authors simply check there example?


First of all, exampledepot.com is an extremely bad site: never ever assume anything found there as being "the truth".

In regex, the $ never matches a character, it matches a position. In (?m) mode, it matches the "empty string" before a line break, or the end of the string. So given the string "abc\r\ndef" the regex ".*abc$.*" does not match since the \r\n isn't present in your regex. The $ matches the position between c and \r.

What you should do is this:

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


I'm not familiar with how community wiki works, but feel free to use this example if deemed useful.

    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"
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜