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年

+1Pattern.quote
redDevil 2014

回答:


175

String.split正規表現の引数が必要です。エスケープ|されていないものは、「空の文字列または空の文字列」を意味する正規表現として解析されますが、これは意図した意味ではありません。


76

分割するパラメーターの構文は正規表現であるため、 '|' ORの特別な意味と '\ |' リテラル '|'を意味します 文字列 "\\ |" 正規表現 '\ |'を意味します つまり、文字 '|'と完全に一致します。


1
この説明をありがとう。ほとんどいつもダブルエスケープを使うのを忘れています。なぜそうなのかわかったので、きっと今から思い出すことができるでしょう。
sufinawaz 2014年

文字列行の値にパイプ文字が含まれている場合はどうなりますか?エスケープされたパイプを分割せずに分割するにはどうすればよいですか\ | ?
AlexandreJ

@AlexandreJ次のような行を分割する方法を尋ねSome|Delimited|Text|With|An\|Embedded|Pipe|Charてい("Some", "Delimited", "Text", "With", "An\|Embedded", "Pipe", "Char")ますか?split関数はこのようなエスケープをサポートしていませんが、この場合に機能する正規表現を作成できる場合があります。(?<!\\)\|line.split("(?<!\\\\)\\|");
たとえば、

6

あなたは単にこれを行うことができます:

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

正規表現「yourString.split( "\\ |")」を使用するには、\をエスケープする必要があります。これは正しい式です。
mautrok
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.