Java中的RegEx:如何处理换行符

use*_*663 26 java regex line-breaks

我目前正在尝试学习如何使用正则表达式,所以请忍受我的简单问题.例如,假设我有一个输入文件,其中包含由换行符分隔的一堆链接:

www.foo.com/Archives/monkeys.htm
Monkey网站的描述.

www.foo.com/Archives/pigs.txt
Pig网站的描述.

www.foo.com/Archives/kitty.txt
Kitty网站的描述.

www.foo.com/Archives/apple.htm
Apple网站的描述.

如果我想获得一个网站及其描述,这个正则表达式似乎适用于测试工具: .*www.*\\s.*Pig.*

但是,当我尝试在我的代码中运行它时似乎不起作用.这个表达是否正确?我尝试用"\n"替换"\ s",但它似乎仍无法正常工作.

Ala*_*ore 57

这些行可能\r\n在您的文件中分隔.两个\r(回车)和\n(换行)都被认为是Java正则表达式中的行分隔符,并且.元字符将不匹配任何一个. \s将匹配这些字符,因此它会消耗\r,但是会与之.*匹配\n,但会失败.您的测试人员可能只是\n用来分隔消耗的线路\s.

如果我是对的,更改\s\s+[\r\n]+应该让它工作.在这种情况下,这可能就是您需要做的所有事情,但有时您必须恰好匹配一个行分隔符,或者至少跟踪您匹配的数量.在这种情况下,您需要一个与三种最常见的行分隔符类型中的任何一种完全匹配的正则表达式:\r\n(Windows/DOS),\n(Unix/Linus/OSX)和\r(较旧的Mac).这些中的任何一个都可以:

\r\n|[\r\n]

\r\n|\n|\r
Run Code Online (Sandbox Code Playgroud)

更新:从Java 8开始,我们有另一种选择 \R.它匹配任何行分隔符,不仅包括Unicode标准\r\n定义的其他几个行分隔符.它相当于:

\r\n|[\n\x0B\x0C\r\u0085\u2028\u2029]
Run Code Online (Sandbox Code Playgroud)

以下是您可以使用它的方法:

(?im)^.*www.*\R.*Pig.*$
Run Code Online (Sandbox Code Playgroud)

i选项使其不区分大小写,m并将其置于多行模式,允许^$在行边界匹配.

  • 不允许原始 '\R' java 8 final :/ (3认同)
  • @Davinder Singh 的答案有双反斜杠,以补偿 java 编译器对字符串文字的解码。也许,乔的观察与尝试使用单个反斜杠后跟新的正则表达式字母有关。这可能会在编译时变成非法的 Java 字符串文字。按照达文德的例子,我想使用双反斜杠应该对乔有用。 (2认同)

jav*_*bic 12

为了将来参考,还可以将Pattern.DOTALL标志用于".".甚至匹配\ r或\n.

例:

假设我们正在解析像这样的一个http标题行的字符串(每行以\ 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
Run Code Online (Sandbox Code Playgroud)

这种模式:

final static Pattern PATTERN_LOCATION = Pattern.compile(".*?Location\\: (.*?)\\r.*?", Pattern.DOTALL);
Run Code Online (Sandbox Code Playgroud)

可以使用"matcher.group(1)"解析位置值.

"." 在上面的模式中将匹配\ r和\n,所以上面的模式实际上可以从http标题行解析'Location',其中可能在目标行之前或之后有其他标题(不是这是推荐的方式)解析http标头).

此外,您可以在模式中使用"?s"来实现相同的效果.

如果你这样做,你可能最好使用Matcher.find().


mae*_*ics 2

对我有用:

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");
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

也许问题出在您使用 Pattern 和 Matcher 对象的方式上?