Java入門:Stringクラス(切り出し・分割・結合)&正規表現で文字列自由自在!
- ツイート
-
- 2023/04/12
Javaには文字列の加工を行うためのメソッドが多く存在します。それらのメソッドを適切に組み合わせることで、自由自在に文字列の編集を行うことができます。今回はそんなJavaを使った基本的な文字列編集テクニックを、具体的な事例を挙げながらご紹介します。
目次
Javaを使えば大量のデータ処理も簡単
Javaを使うことで、顧客データの編集を手作業で行うよりも短時間で間違いなく、楽に行うことができるようになります。大量のデータ処理も、Javaのスキルがあれば簡単に処理が可能です。
今回は顧客データ管理を事例として文字列編集のテクニックを見ていきましょう。
データ管理の代表的な方法は、コンマ区切りのテキストファイルでデータを保存する方法です。氏名・メールアドレス・郵便番号・住所を含む、以下のような架空の顧客データがあるとします。
西川 貴浩,xxxx@gmail.com,041-0604,北海道函館市元村町 浅井 唯,xxxx@yahoo.co.jp,144-0034,東京都大田区西糀谷 浜口 英則,yyyy@gmail.com,880-0879,宮崎県宮崎市宮崎駅東
この顧客データに対して、Javaを使って以下の編集を行っていきます。
- 氏名のみ、住所のみなど特定のデータだけを取り出す
- 郵便番号と住所をつなげて1つのデータにする
- メールアドレスのドメイン部分を切り出す
Stringクラスを使って顧客データを編集しよう
顧客データは通常、文字列(=文字の集まり)としてファイルまたはデータベースに保存されていますが、Javaで文字列を扱うときはStringクラスを使います。Stringクラスを使うコード例を以下に示します。
String str = "文字列"; // Stringオブジェクトを生成 System.out.println(str); // 文字列 と表示される
Stringクラスは文字列に対して分割や結合、切り出しなどの加工を行うためのメソッドを備えています。ここからは実際に、Stringクラスの代表的なメソッドを使い、先ほど述べた顧客データの編集を行う方法を紹介していきます。
splitメソッドを用いた文字列の分割
先ほどの顧客データをもう一度掲載します。
西川 貴浩,xxxx@gmail.com,041-0604,北海道函館市元村町 浅井 唯,xxxx@yahoo.co.jp,144-0034,東京都大田区西糀谷 浜口 英則,yyyy@gmail.com,880-0879,宮崎県宮崎市宮崎駅東
このデータの特徴は氏名から住所までが、コンマ区切りで保存されている点です。Javaにはファイルに書かれた内容を1行ずつ読み込む機能があります。
上記の顧客データがsample.csvというファイルに保存されていたとき、ファイルの中身を1行ずつ読み込んで出力するコードは以下のようになります(ファイルを読み込む際は例外処理の記述が必要ですが、今回は説明を簡単にするために省略しています)。
// 顧客データファイルの名前(場所)を指定する Path path = Paths.get("sample.csv"); // データを1行ずつに分けてリストに読み込む List<String> lines = Files.readAllLines(path); // 読み込んだデータを1行ずつ出力する for (String line : lines) { System.out.println(line); }
しかし、このままでは氏名から住所までが1つの文字列としてStringオブジェクトとして格納されているため、氏名のみや住所のみを取り出すことができません。ここで使うのがStringクラスのsplitというメソッドです。まずsplitメソッドの構文を確認しましょう。
<文字列>.split(<区切り文字>)
splitメソッドは、引数で指定した区切り文字で文字列を分割し、分割後の文字列の配列を返します。例えば、半角スペースで区切られた氏名を分割したい場合は以下のようなコードになります。
String fullName = "山田 太郎"; String[] names = fullName.split(" "); System.out.println("姓: " + names[0] + ", 名: " + names[1]); // 姓: 山田, 名: 太郎 と表示される
splitメソッドの区切り文字にコンマを指定すれば、コンマ区切りのデータを分割することができます。以下のサンプルコードは、コンマ区切りのデータをファイルから読み込み、氏名のみをリストに格納します。
// 氏名データを格納するリスト List<String> names = new ArrayList<>(); Path path = Paths.get("sample.csv"); List<String> lines = Files.readAllLines(path); for (String line : lines) { // コンマで行を分割 String[] data = line.split(","); // 分割後の1つ目の文字列(=氏名)をリストに追加 names.add(data[0]); } // 氏名を1つずつ表示 for (String name : names) { System.out.println(name); }
これでコンマ区切りのデータから、特定のフィールド(上の例では氏名)を取り出して処理することができるようになりました。splitメソッドを使えば、区切り文字がコンマではなくスペースやコロンになったとしても、引数に与える文字列を変えるだけで簡単に対応することができます。
concatメソッドを用いた文字列の結合
【元の顧客データ】
西川 貴浩,xxxx@gmail.com,041-0604,北海道函館市元村町 浅井 唯,xxxx@yahoo.co.jp,144-0034,東京都大田区西糀谷 浜口 英則,yyyy@gmail.com,880-0879,宮崎県宮崎市宮崎駅東
このデータでは、郵便番号と住所がそれぞれコンマで区切られて分かれていますが、これらをまとめて1つのフィールドにしたい場合を考えます。ここではStringクラスのconcatというメソッドを使って、データを編集していきます。concatメソッドの構文は次の通りです。
<文字列>.concat(<文字列>)
concatメソッドは、引数で指定した文字列を元の文字列の最後に結合し、結合後の文字列を返します。例えば、名字と名前を結合し、1つの文字列にしたい場合は以下のようなコードになります。
String familyName = "山田"; String firstName = "太郎"; // 名字と名前を結合 String fullName = familyName.concat(firstName); System.out.println(fullName); // 山田太郎 と表示される
郵便番号と住所を結合する場合は <郵便番号>.concat(<住所>) と書けばよさそうですが、例えば以下の要求があるとします。
- 郵便番号の前に〒マークをつける
- 郵便番号と住所の間に半角スペースを入れる
複数の文字列を結合したい場合には、以下のようにconcatメソッドを複数つなげて使うことができます。
<文字列>.concat(<文字列>).concat(<文字列>).concat(<文字列>)...
そのため、以下のように書けば前述の要求を満たして郵便番号と住所を結合させることができます。
String postalCode = "041-0604"; String address = "北海道函館市元村町"; // 〒と半角スペースを加えて住所を結合 String fullAddress = "〒".concat(postalCode) .concat(" ") .concat(address); // 〒041-0604 北海道函館市元村町 と表示される System.out.println(fullAddress);
また、文字列の結合は+演算子を使って行うこともできますが、処理速度の面からconcatメソッド(もしくはStringBufferクラスやStringBuilderクラスのappendメソッド)の利用をおすすめします。
// +演算子を使って住所を結合 String fullAddress = "〒" + postalCode + " " + address; // concatを使った場合と同じ結果が得られる System.out.println(fullAddress);
以下のサンプルコードは、sample.csvというファイルに書かれたコンマ区切りの顧客データの郵便番号と住所を結合し、sample_new.csvというファイルに修正後の顧客データを書き込みます。
// 元の顧客データ Path inputPath = Paths.get("sample.csv"); List<String> inputLines = Files.readAllLines(inputPath); // 修正後の顧客データ(書き込み先) Path outputPath = Paths.get("sample_new.csv"); List<String> outputLines = new ArrayList<>(); for (String inputLine : inputLines) { // コンマで行を分割 String[] data = inputLine.split(","); String fullName = data[0]; String mailAddress = data[1]; String postalCode = data[2]; String address = data[3]; // 郵便番号と住所を結合 String fullAddress = "〒".concat(postalCode) .concat(" ") .concat(address); // 氏名、メールアドレス、結合した住所をコンマ区切りで結合 String outputLine = String.join(",", fullName, mailAddress, fullAddress); outputLines.add(outputLine); } // 修正後の顧客データをファイルに書き込み Files.write(outputPath, outputLines, StandardCharsets.UTF_8);
上記のサンプルコードでは、一度分割したコンマ区切りの文字列を再びコンマ区切りに文字列に戻すためにString.joinメソッドを使っています。String.joinメソッドの構文は以下の通りです。
String.join(<区切り文字>, <文字列>, <文字列>, ...)
joinメソッドは第2引数以降に指定した複数の文字列を、第1引数で指定した区切り文字を加えて結合します。そのため、第1引数にコンマを指定し、その後に結合させたい文字列を指定すれば、コンマ区切りの文字列を作ることができます。
結局、元の顧客データは以下のように修正されます。
西川 貴浩,xxxx@gmail.com,〒041-0604 北海道函館市元村町 浅井 唯,xxxx@yahoo.co.jp,〒144-0034 東京都大田区西糀谷 浜口 英則,yyyy@gmail.com,〒880-0879 宮崎県宮崎市宮崎駅東
これで郵便番号と住所が結合した顧客データを作ることができました。この方法を応用すれば、任意のデータを結合したり、データに何らかの文字列を追加したりすることが自由自在にできるようになります。
substringメソッドを用いた文字列の切り出し
再び先ほどの顧客データを見てみましょう。
【元の顧客データ】
西川 貴浩,xxxx@gmail.com,041-0604,北海道函館市元村町 浅井 唯,xxxx@yahoo.co.jp,144-0034,東京都大田区西糀谷 浜口 英則,yyyy@gmail.com,880-0879,宮崎県宮崎市宮崎駅東
今度は、顧客データからGmailの利用者数を調べましょう。Gmailのドメイン(@以降のこと)はgmail.comであるため、メールアドレスの@以降の文字列を切り出してgmail.comと一致するデータを数えればよさそうです。
ここで使うメソッドが、Stringクラスのsubstringというメソッドです。substringメソッドの構文は以下のようになっています。
<文字列>.substring(<開始位置>, <終了位置>)
このメソッドは、第1引数で指定した位置から、第2引数で指定した位置までの文字列を返します。切り出しの開始位置および終了位置は、最初の文字の位置を0として数えます。
ここで気をつけなければならない点が、切り出される文字は終了位置の手前までであるということです。例えば3文字目から6文字目を切り出したいときは、切り出し開始位置が2、終了位置が6となるため、引数に(2, 6)と指定します。
String str = "investment".substring(2,6); System.out.println(str); // 「vest」(ベスト、チョッキ)と表示される
また、終了位置を指定しない場合は開始位置から文字列の最後までを切り出します。
String str = "recall".substring(2); System.out.println(str); // callと表示される
したがって、メールアドレスのドメインを切り出すには、substringメソッドで開始位置を@の次の文字に指定して切り出すことができます。メールアドレス中の@の位置を知るためには、StringクラスのindexOfメソッドを使います。indexOfメソッドの構文は以下の通りです。
<文字列>.indexOf(<文字列>)
indexOfメソッドは、引数に指定した文字列が最初に出現した位置(=インデックス)を返します。例えば、文字列内の@の位置を知りたいときは、以下のように書きます。
int index = "123@test.com".indexOf("@"); System.out.println(index); // 3 と表示される
ここまでに学んだテクニックを組み合わせて、以下の手順でGmailの利用者数を調べることができます。
- メールアドレスの@の位置を調べる
- @以降の文字列(ドメイン)を切り出し
- ドメインがgmail.comとなっているデータを集計
実際に上記のような処理を行うコードは、次のようになります。
// 顧客データをファイルから読み込み Path path = Paths.get("sample.csv"); List<String> lines = Files.readAllLines(path); // Gmailを使っている顧客の人数 int numberOfGmailUsers = 0; // 全メールアドレスに対して、{}内の処理を適用する for (String line : lines) { // コンマで行を分割し、メールアドレスを取り出す String[] data = line.split(","); String mailAddress = data[1]; // メールアドレスのドメイン部分の切り出し int index = mailAddress.indexOf("@"); String domain = mailAddress.substring(index + 1); // ドメインがgmail.comだった場合、人数を1増やす if (domain.equals("gmail.com")) { numberOfGmailUsers++; } } System.out.println("Gmailを使っているのは" + numberOfGmailUsers + "人です。");
これで顧客データからGmailの利用者数を調べることができました。このようにsubstringメソッドを応用すれば、データの中から自由に文字列を切り出し、データの分析までできるようになります。
正規表現を利用してできること
以下の顧客データの管理を考えます。
西川 貴浩, xxxx@gmail.com, 041-0604, 北海道函館市元村町 浅井 唯, xxxx@yahoo.co.jp, 144-0034, 東京都大田区西糀谷 浜口 英則, yyyy@gmail.com, 880-0879, 宮崎県宮崎市宮崎駅東
先ほどまで見ていた顧客データとの違いは、コンマの後にスペースが含まれている点です。このデータをこれまでのようにsplitメソッドを使ってコンマで分割すると、分割後の文字列に不要なスペースが含まれてしまいます。
// コンマの後に半角スペースが含まれたデータを分割 String line = "山田 太郎, 123@test.com"; String[] data = line.split(","); // 先頭に無駄なスペースが含まれたメールアドレスが表示される System.out.println(data[1]);
さらに上記の顧客データでは、コンマの後に含まれるスペースの数もバラバラであるため、区切り文字をコンマ+スペースにしてもうまく分割することができません。
このようなケースで有効な手段が正規表現です。正規表現とは、文字列の集合を1つの文字列で表現する方法のことです。つまり、正規表現を使うとコンマ+任意の数のスペースを1つの文字列で表すことができます。
正規表現では空白文字(スペースやタブなど)を\sと表します。また、任意の数の繰り返しを*(アスタリスク)で表現します。よって、「コンマ+任意の数のスペース」は正規表現で以下のように表されます。
,¥s*
splitメソッドは区切り文字として正規表現を用いることができます。したがって、以下のように書くと、コンマ+スペースで区切られたデータを分割することができます。
// 正規表現を使ってコンマの後に半角スペースが含まれたデータを分割 String line = "山田 太郎, aaa@test.com"; String[] data = line.split(",¥¥s*"); // 無駄なスペースが含まれないメールアドレスが表示される System.out.println(data[1]);
正規表現の*(アスタリスク)は直前の文字の0回以上の繰り返しを表すため、コンマの後にスペースが無い場合でも正しく分割されます。ここで、Javaの文字列で\を使うためには\\と2つ続けて書かなければいけないことに注意してください。
これでコンマ+スペースで区切られた顧客データを正しく分割できるようになりました。正規表現はとても優れた文字列の表現方法であり、どのようなデータの区切り方にも対応可能です。他にも正規表現は文字列の検索、置換、抽出で効果を発揮します。
Javaには正規表現を使うことのできるメソッドが数多く用意されています。興味のある方はぜひ調べてみてください。
おわりに
今回はJavaのStringクラスを使った顧客データの管理方法を紹介しました。ご紹介したのは文字列の分割、結合、切り出しといった基本的な操作をご紹介しましたが、これだけでも使い方によってさまざまなデータの編集ができることがお分かりいただけたでしょう。
Stringクラスには他にも文字列を操作するための多くのメソッドがあり、これらを習得すればさらにできることの幅が広がります。例えば、入力データをチェックして全角英数字を半角英数字に変換したり、データを一定の書式にそろえたりすることができるようになります。ぜひJavaをマスターして効率的なデータ管理を実現しましょう。
インターネット・アカデミーでは、Javaによる大規模WebシステムやAndroidアプリ開発を学ぶことができる講座を開講しています。プロ講師から現場のノウハウを学んで、ITやWeb業界で活躍してみませんか。ご興味のある方は、ぜひお気軽に無料体験レッスンにご参加ください。
大規模Webシステムをオラクル認定校で学ぶ
Java講座Javaのプログラミングの基礎から、顧客管理システムやファイル共有システム、さらには大規模なWebシステムの開発まで学び、未経験から即戦力のJavaプログラマーを目指すことができます。
相談してコースを選びたい方はカウンセラーに無料で相談
※無理な勧誘は一切ありません
無料で相談してみる