
JavaのString.replaceとは?文字・文字列を置換するためのString.replaceの使い方
JavaのString.replaceは、文字列に含まれる特定の文字・文字列を、指定されたものに置換するメソッドです。
類似のメソッドにString.replaceAll/replaceFirstがありますが、こちらは「正規表現」と呼ばれるパターンを指定して置換する文字列を探しますので、少しだけ扱いが難しいものです。
この記事ではString.replaceに限定して使い方や活用方法をお伝えします。String.replaceAll/replaceFirstは別記事で扱っていますので、興味があればそちらもぜひご覧になってください。
※この記事のサンプルは、Java 10の環境で動作確認しています。
1.String.replaceは文字・文字列を置換する
String.replaceは、Stringが持つ文字列中にある特定の文字・文字列を、指定した文字・文字列に「全て」置換した文字列を戻すメソッドです。
なお、replaceされた元のStringはそのままです。
置換するものを文字・文字列のどちらにするかにより、二つのメソッドが選べます。
public String replace(char oldChar, char newChar) oldChar - 以前の文字。 newChar - 新しい文字。 public String replace(CharSequence target, CharSequence replacement) target - 置換されるchar値のシーケンス replacement - char値の置換シーケンス
ここのポイントは「全て」という所です。「ここの部分だけ置換したい」ということが、残念ながらできません。
String str = "ABCDABCD"; String str2 = str.replace('A', 'あ'); System.out.println(str2); // → あBCDあBCD String str3 = str.replace("BC", "びーしー"); System.out.println(str3); // → AびーしーDAびーしーD System.out.println(str); // → ABCDABCD、元のStringはそのまま
指定した文字・文字列が存在しなかった場合は、元の文字列がそのまま戻ります。
String str = "ABCDABCD"; String str2 = str.replace('Z', 'あ'); System.out.println(str2); // → ABCDABCD、そのまま String str3 = str.replace("ZZZ", "あいうえお"); System.out.println(str3); // → ABCDABCD、そのまま
置換後の文字列に空文字列(長さ0の文字列)を指定すると、実質的に文字を削除することになります。ですが、nullを指定するとNullPointerExceptionが発生しますので、エラーを出したくない方はきちんとチェックした方がいいかもしれませんね。
String str = "ABCDABCD"; String str2 = str.replace("A", ""); System.out.println(str2); // → BCDBCD String str3 = str.replace("A", null); System.out.println(str3); // → NullPointerException!!
なお、戻り値がStringなので、以下のようにメソッドチェーンとすると、必要なだけいくらでもreplaceし続けられたりします。変換を一気に行いたい場合に使います。
String str = "ABCDABCD"; String str2 = str.replace("A", "あ").replace("B", "い").replace("C", "う").replace("D", "え"); System.out.println(str2); // → あいうえあいうえ
2.【応用】String.replaceの活用例
2-1.CSVからTSVへ変換する
CSV(comma-separated values、カンマ区切り)をTSV(tab separated values、タブ区切り)に変えるのにreplaceが使えます。
以下のとおり、ごく単純な例ですね。
String csv = "A,B,,D,あいうえお"; String tsv = csv.replace(',', '\t'); System.out.println(csv); // → A,B,,D,あいうえお System.out.println(tsv); // → A B D あいうえお
ただ、少々乱暴なやり方なので、区切り文字以外に‘,’が使われていないかどうかは、必ず確認しましょう。例えば、金額のカンマ表記(“1,000,000”)、欧米の人名表記(“Yamada, Taro”)、会社名(“Co.,ltd”)などが要注意です。
なお、ファイルへ直接行う場合は、例えば以下のようになります。
import java.io.BufferedReader; import java.io.BufferedWriter; import java.nio.file.Files; import java.nio.file.Paths; class ReplaceSample { public static void main(String[] args) throws Exception { try (BufferedReader br = Files.newBufferedReader(Paths.get("sample.csv")); BufferedWriter bw = Files.newBufferedWriter(Paths.get("sample.tsv"));) { String csv = null; while ((csv = br.readLine()) != null) { String tsv = csv.replace(',', '\t') + System.lineSeparator(); bw.write(tsv); } } } }
さらに、Streamを使うと以下のようになります。これだとファイルの内容を全部メモリ上へ一度に読み込むので、もし巨大なファイルを処理するならOutOfMemoryErrorに気を付けてください。
import java.nio.file.Files; import java.nio.file.Paths; import java.util.List; import java.util.stream.Collectors; class ReplaceSample { public static void main(String[] args) throws Exception { List<String> tsv = Files.lines(Paths.get("sample.csv")).map(s -> s.replace(',', '\t')) .collect(Collectors.toList()); Files.write(Paths.get("sample.tsv"), tsv); } }
それにしても、Java 7や8以降だと、ファイルの読み書きはだいぶ楽になりましたね。
2-2.テンプレート内キーワードの入れ替え
何かのテンプレートを用意して、置換したい部分にキーワードを設定し、プログラム上で状況に合わせて置換することは頻繁に行います。例えば、以下のような文面を用意しておいて、と言う感じです。
{customerName}様
弊社のサービス{serviceName}をご利用いただき、ありがとうございます。
お客様の契約されているサービス{serviceName}は、契約期間がもうすぐ満了になります。
もしサービスを継続される場合は「{ymd}」までに契約継続のお手続きをお取りください。
契約継続のお手続きは、以下のURLからお願いいたします。
{url}
こういう文章は、文字列を+で連結したり、StringBuiderにため込む方法でも作れますが、テンプレートをファイルにしておけば文言の修正は簡単ですし、プログラムを直さなくてもいいのでお勧めです。
そして、これをきちんとした文章に仕上げる際に、replaceが使えます。前述の通りreplaceはStringを返すので、メソッドチェーンで書くと楽ですね。
import java.nio.file.Files; import java.nio.file.Paths; import java.util.stream.Collectors; class ReplaceSample { public static void main(String[] args) throws Exception { String template = Files.lines(Paths.get("template.txt")) .collect(Collectors.joining(System.lineSeparator())); // ↑の文面が入っているファイルをStringとして読み取る String replaced = template.replace("{customerName}", "山田太郎").replace("{serviceName}", "XXXクラウド") .replace("{ymd}", "2018/11/15").replace("url", "https://xxxcloud.example.com/contract"); System.out.println(replaced); } }
なお、あらかじめキーワードと変換後の値がMapに入っていれば、以下のようにも行えます。更なる応用としては、置換用のパラメータ自体もファイルに保存しておく、などということはできそうです。
import java.nio.file.Files; import java.nio.file.Paths; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import java.util.stream.Collectors; class ReplaceSample { public static void main(String[] args) throws Exception { // キーワードと値をMapに保存しておく Map<String, String> nameValue = new HashMap<>(); nameValue.put("customerName", "山田太郎"); nameValue.put("serviceName", "XXXクラウド"); nameValue.put("ymd", "2018/11/15"); nameValue.put("url", "https://xxxcloud.example.com/contract"); // テンプレートファイルを読み込んで… String template = Files.lines(Paths.get("template.txt")) .collect(Collectors.joining(System.lineSeparator())); String replaced = template; // 一気に変換!! for (Entry<String, String> e : nameValue.entrySet()) { replaced = replaced.replace("{" + e.getKey() + "}", e.getValue()); } System.out.println(replaced); } }
テンプレートを作るコツは、置換する文字列の前後に何か余分なものを付けておいて(この例では{})、確実にreplaceできるようにすることです。キーワード自体を含めたい場合、入れ替えたくないところまで入れ替わる恐れがあるからですね。
なお、HTMLやXMLなどもつまるところはただの文字列なので、同じようにテンプレートにできます。要は使い方次第なのですね。
<?xml version="1.0" encoding="utf-8" ?> <information> <customer name="{customerName}" /> <service>{serviceName}</service> <serviceEndYmd>{ymd}</serviceEndYmd> <url>{url}</url> </information>
3.まとめ
String.replaceは、文字列中にある何かの文字・文字列を、指定したものに置換するメソッドです。機能自体は非常に単純ですが、使い方次第で色々と便利なものです。
何かをテンプレートにしておいて、必要な所だけ入れ替えて使うことは、色々なフレームワークでも見かけるものです。一見難しそうでも、実はString.replaceで簡単に実現できるので、活用方法の一つとしてぜひ覚えておいてください。
コメント