RegEx in Java: how to deal with newline

后端 未结 6 1242
小蘑菇
小蘑菇 2020-12-01 05:17

I am currently trying to learn how to use regular expressions so please bear with my simple question. For example, say I have an input file containing a bunch of links separ

相关标签:
6条回答
  • 2020-12-01 05:38

    Works for me:

    import java.util.regex.Pattern;
    import java.util.regex.Matcher;
    public class Foo {
      public static void main(String args[]) {
        Pattern p = Pattern.compile(".*www.*\\s.*Pig.*");
        String s = "www.foo.com/Archives/monkeys.htm\n"
                 + "Description of Monkey's website.\n"
                 + "\n"
                 + "www.foo.com/Archives/pigs.txt\n"
                 + "Description of Pig's website.\n"
                 + "\n"
                 + "www.foo.com/Archives/kitty.txt\n"
                 + "Description of Kitty's website.\n"
                 + "\n"
                 + "www.foo.com/Archives/apple.htm\n"
                 + "Description of Apple's website.\n";
        Matcher m = p.matcher(s);
        if (m.find()) {
          System.out.println(m.group());
        } else {
          System.out.println("ERR: no match");
        }
      }
    }
    

    Perhaps the problem was with the way you were using the Pattern and Matcher objects?

    0 讨论(0)
  • 2020-12-01 05:43

    For future reference, one can also use the Pattern.DOTALL flag for "." to match even \r or \n.

    Example:

    Say the we are parsing a single string of http header lines like this (each line ended with \r\n)

    HTTP/1.1 302 Found
    Server: Apache-Coyote/1.1
    Cache-Control: no-cache, no-store, max-age=0, must-revalidate
    Pragma: no-cache
    Expires: 0
    X-Frame-Options: SAMEORIGIN
    Location: http://localhost:8080/blah.htm
    Content-Length: 0
    

    This pattern:

    final static Pattern PATTERN_LOCATION = Pattern.compile(".*?Location\\: (.*?)\\r.*?", Pattern.DOTALL);
    

    Can parse the location value using "matcher.group(1)".

    The "." in the above pattern will match \r and \n, so the above pattern can actually parse the 'Location' from the http header lines, where there might be other headers before or after the target line (not that this is a recommended way to parse http headers).

    Also, you can use "?s" inside the pattern to achieve the same effect.

    If you are doing this, you might be better off using Matcher.find().

    0 讨论(0)
  • 2020-12-01 05:47

    This version matches newlines that may be either Windows (\r\n) or Unix (\n)

    Pattern p = Pattern.compile("(www.*)((\r\n)|(\n))(.*Pig.*)");
    String s = "www.foo.com/Archives/monkeys.htm\n"
               + "Description of Monkey's website.\n"
               + "\r\n"
               + "www.foo.com/Archives/pigs.txt\r\n"
               + "Description of Pig's website.\n"
               + "\n"
               + "www.foo.com/Archives/kitty.txt\n"
               + "Description of Kitty's website.\n"
               + "\n"
               + "www.foo.com/Archives/apple.htm\n"
               + "Description of Apple's website.\n";
    Matcher m = p.matcher(s);
    if (m.find()) {
      System.out.println("found: "+m.group());
      System.out.println("website: "+m.group(1));
      System.out.println("description: "+m.group(5));
    }
    System.out.println("done");
    
    0 讨论(0)
  • 2020-12-01 05:57
    String str="I am  a   "+"\n  Man    of  Peace"+"\t"+"   .";
    
    str=str.replaceAll("[\\s|\\t|\\r\\n]+"," ").trim();
    System.out.println(str);
    

    This above example works for tabSpaces, newLines, and normal spaces. And I have used the trim method of java.lang.String to remove all the additional spaces in 'str'. I hope this helps you and other amazing people here.

    0 讨论(0)
  • 2020-12-01 06:02

    The lines are probably separated by \r\n in your file. Both \r (carriage return) and \n (linefeed) are considered line-separator characters in Java regexes, and the . metacharacter won't match either of them. \s will match those characters, so it consumes the \r, but that leaves .* to match the \n, which fails. Your tester probably used just \n to separate the lines, which was consumed by \s.

    If I'm right, changing the \s to \s+ or [\r\n]+ should get it to work. That's probably all you need to do in this case, but sometimes you have to match exactly one line separator, or at least keep track of how many you're matching. In that case you need a regex that matches exactly one of any of the three most common line separator types: \r\n (Windows/DOS), \n (Unix/Linus/OSX) and \r (older Macs). Either of these will do:

    \r\n|[\r\n]
    
    \r\n|\n|\r
    

    Update: As of Java 8 we have another option, \R. It matches any line separator, including not just \r\n, but several others as defined by the Unicode standard. It's equivalent to this:

    \r\n|[\n\x0B\x0C\r\u0085\u2028\u2029]
    

    Here's how you might use it:

    (?im)^.*www.*\R.*Pig.*$
    

    The i option makes it case-insensitive, and the m puts it in multiline mode, allowing ^ and $ to match at line boundaries.

    0 讨论(0)
  • 2020-12-01 06:02

    try this

    ([^\r]+\r[^\r])+
    
    0 讨论(0)
提交回复
热议问题