为什么String.split需要对管道定界符进行转义?


140

我试图解析一个文件,该文件的每一行都用管道定界值。当我没有在split方法中转义管道定界符时,它不能正常工作,但是在我如下所示转义管道后,它却可以正常工作。

private ArrayList<String> parseLine(String line) {
    ArrayList<String> list = new ArrayList<String>();
    String[] list_str = line.split("\\|"); // note the escape "\\" here
    System.out.println(list_str.length);
    System.out.println(line);
    for(String s:list_str) {
        list.add(s);
        System.out.print(s+ "|");
    }
    return list;
}

有人可以解释为什么该split()方法需要转义管道字符吗?


13
以下答案回答了“为什么”,但仅供参考,如果您想匹配文字字符串,您可能还会查看Pattern.quote。它需要a String并返回一个String与输入匹配的正则表达式(即,它为您完成了所有转义操作)。
yshavit 2012年

+1代表Pattern.quote
redDevil

Answers:


175

String.split需要一个正则表达式参数。未转义的|被解析为正则表达式,表示“空字符串或空字符串”,这不是您的意思。


76

因为该参数拆分的语法是一个正则表达式,所以“ |”中的 具有OR的特殊含义,并且带有'\ |' 表示文字“ |” 因此字符串“ \\ |” 表示正则表达式“ \ |” 这意味着完全匹配字符“ |”。


1
感谢您的解释。我几乎总是忘记使用双重转义。现在,我知道为什么会这样,它肯定会从现在起帮助我记住。
sufinawaz 2014年

如果String行的值包含一些Pipe字符,会发生什么情况?您将如何在不拆分转义管道的情况下进行拆分 ?
AlexandreJ

@AlexandreJ您是否在问如何将看起来像这样的行拆分Some|Delimited|Text|With|An\|Embedded|Pipe|Char("Some", "Delimited", "Text", "With", "An\|Embedded", "Pipe", "Char")?split函数不支持这样的转义,但是您可以制作出适用于这种情况的正则表达式,例如在group后面使用零宽度的否定断言:(?<!\\)\|那是line.split("(?<!\\\\)\\|");
dlamblin

6

您可以简单地做到这一点:

String[] arrayString = yourString.split("\\|");

您必须转义\才能使用正则表达式“ yourString.split(” \\ |“)”这是正确的公式。
mautrok 2015年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.