真 もわ爛漫

しゃーら、しゃーらしゃーら

Java の String#replaceAll() 解

Sun Java 1.6 では"Exception を吐いて落ちる"が正解。

replaceAll
public String replaceAll(String regex, String replacement)

指定された正規表現に一致する、この文字列の各部分文字列に対し、指定された置換を実行します。
このフォームのメソッド呼び出し str.replaceAll(regex, repl) では、次の式と正確に同じ結果が得られます。
Pattern.compile(regex).matcher(str).replaceAll(repl)

つまり"\\"はStringの表現で"\"として扱われ、それが正規表現エンジンに取り込まれて謎な動作になる、つーことらしい。

目的のコードは正しくはこう書くらしい。

public class Test {
  public static void main(String argv[]) {
    System.out.println("\\,\\\\,"
                       .replaceAll("\\\\\\\\", "\\\\")
                       .replaceAll("\\\\,", ","));
  }
}

ちなみに今日まで戦っていたコードの中に、この挙動が理解できなかったためか、replaceAll()がreplace()になっているケースがあったようななかったような。