【Java】Patternを使ってマッチする文字列を抽出する方法

今回はJavaでPatternを使った文字列の抽出をご紹介します。

実務で以下のような要件を満たす必要がありまして、このようなケースで有効な方法です。

  • 外部システムからAPI経由で特定のファイル名が連携される
  • そのファイル名には日付とIDが含まれている
  • その日付とIDを抽出して別なファイル名として置き換える必要がある

外部から連携されるファイル名は日付とID部分のみが動的に変更されますが、そのほかの文字列は固定化されているという前提です。

このように、パターンが決まっている文字列から一部分の文字列を抽出する際にPatternクラスが使えます。

例題を作ってみる

では、例として外部から連携される文字列を「sample_file_test_日付_ID」とすることにします。

日付はyyyyMMdd形式、IDは10桁の数字とした場合、正規表現では以下のように表せます。

sample_file_test_[0-9]{8}_[0-9]{10}

これをパターンとして定義しておいて、連携される実際のファイル名をマッチさせて日付とIDを抽出します。


// パターンとなる文字列(抽出したい部分はカッコで囲むことでグループ化され抽出できるようになる)
final String regex = "sample_file_test_([0-9]{8})_([0-9]{10})";

// 実際に連携されるファイル名
final String fileName = "sample_file_test_20200101_1923482036";

// パターンとなる文字列を渡してPatternを生成
Pattern pattern = Pattern.compile(regex);

// Patternにファイル名を渡してMatcherを生成
Matcher matcher = pattern.matcher(fileName);

// matchesメソッドはパターンにマッチすればtrue、マッチしなければfalseを返す
if (!matcher.matches()) {
    // マッチしないので形式エラー
    System.out.println("ファイル名の形式に誤りがあります。[ファイル名:" + fileName + "]");
    return;
}

// マッチした文字列はgroupメソッドで取得可能
String date = matcher.group(1);
String id = matcher.group(2);

System.out.println(MessageFormat.format("date:{0}, id:{1}", date, id));

実際にJavaで実装すると上記のようになります。

ポイント

  1. Patternクラスのcompileメソッドを使ってパターンを定義する
  2. 1で引数に渡すパターン文字列のうち、抽出したい部分を()で囲むことで4のgroupメソッドで抽出可能になる
  3. さらに、Patternに対してマッチさせたい文字列を与える(今回の場合はファイル名)
  4. Matcherのgroupメソッドを使ってマッチする部分を抽出する

上記のソースでは、連携されるファイル名が「sample_file_test_20200101_1923482036」となっており、matcherのgroupメソッドより日付として「20200101」を、IDとして「1923482036」を取得することが出来ます。

これを実行すると以下のような結果になります。

date:20200101, id:1923482036

matcherのmatchesメソッドを使えば、パターンにマッチしているかどうかを取得することも出来るので、今回の例だと連携されたファイル名がそもそも形式的に合っているかどうかのチェックを行うことも出来ます。

例えば、不正なファイル名として「test_test_test_20200101_1923482036」を与えると以下のような結果になります。

ファイル名の形式に誤りがあります。[ファイル名:test_test_test_20200101_1923482036]

まとめ

パターン化された文字列から一部の文字列を抽出する場合はPatternクラスを使うことで実現できます。

そもそもパターンとマッチしているか?マッチしている場合はその部分を抽出する、といったケースで使うことが出来ます。

Patternクラスを使わない場合、区切り文字でsplitして、その配列のn番目を取り出して・・・のような実装になってしまうと思います。

配列のn番目を取り出すといった実装は、見た目的にもカッコよくありませんし、思わぬバグにつながることもあるので、是非Patternクラスを使いこなせるようにしましょう。

コメント