【Java】StringのreplaceとreplaceAllの違いについて

java

StringのreplaceとreplaceAllの違いについて解説しています。

以下の例外が発生していて困っている方に参考にしてもらえればと思います。

[スポンサーリンク]
java.util.regex.PatternSyntaxException: Unexpected internal error near index 1

replaceとreplaceAllの違い

replaceは、マッチした文字をそのまま置き換えます。
replaceは、マッチした文字を正規表現として置き換えます。

replaceの実装例

replaceの第一引数を[0-9]を正規表現として扱わず、そのまま置き換えています。

    	String beforeReplace = "[0-9]test";
    	String afterReplace = beforeReplace.replace("[0-9]", "100");
    	System.out.println("replace 前 : " + beforeReplace);
    	System.out.println("replace 後 : " + afterReplace);

実行結果

>実行結果
replace 前 : [0-9]test
replace 後 : 100test

replaceAllの実装例

replaceAllの第一引数を[0-9]を正規表現として扱って、値を置き換えています。

    	String beforeReplace = "[0-9]test";
    	String afterReplace = beforeReplace.replaceAll("[0-9]", "100");
    	System.out.println("replace 前 : " + beforeReplace);
    	System.out.println("replace 後 : " + afterReplace);

実行結果

>実行結果
replace 前 : [0-9]test
replace 後 : [100-100]test

PatternSyntaxExceptionが発生する原因

こちらのプログラムだとPatternSyntaxExceptionが発生します。
原因は¥を正規表現として扱って処理しているためです。

    	String beforeReplace = "test\\";
    	String afterReplace = beforeReplace.replaceAll("\\", "100");
    	System.out.println("replace 前 : " + beforeReplace);
    	System.out.println("replace 後 : " + afterReplace);

実行結果

>実行結果
Exception in thread "main" java.util.regex.PatternSyntaxException: Unexpected internal error near index 1
\

もし¥を正規表現としてマッチさせて置き換えたいのであれば、以下のように¥¥¥¥とすればOKです。
ややこしいですが。。

    	String beforeReplace = "test\\";
    	String afterReplace = beforeReplace.replaceAll("\\\\", "100");
    	System.out.println("replace 前 : " + beforeReplace);
    	System.out.println("replace 後 : " + afterReplace);

実行結果

>実行結果
replace 前 : test\
replace 後 : test100

さいごに

正規表現を使いたいのであれば、MatcherとPatternを使ったほうが、第三者が初見で見た時にわかりやすいソースになると思います。

人のソースコードをレビューする時、replaceAllが出てきたら気をつけて見るようにしましょう!
それでは!