お役立ち情報

Javaの正規表現の使い方とチェックしなければならないポイント

正規表現

正規表現とは、複数の文字列の共通パターンを抜き出して記号化したものです。解説する人によって表現はまちまちなのですが、たとえば以下の文字列を正規表現にしてみます。

123-4567

[0-9]{3}-[0-9]{4}

これは郵便番号の形式ですが、[0-9]は0~9の数字を意味しています。次に{3}{4}はそれぞれ数字がいくつ続くかを意味しています。つまり、0~9の数字が3回続いてハイフンが入り、さらに0~9の数字が4回続く、ということを記号化して表現しているのです。

厳密には少々異なりますが、いわば数学の公式のようなものです。複数の具体例から共通点を抽象化しているわけです。難しい言葉を使うと、演繹と帰納のイメージになります。よくわからなければ無視で良いのですが、具体的な文字列を抽象化して表記したものが正規表現、と覚えておくとわかりやすいかもしれません。

表現は人それぞれですが、上記の概念を自分なりの言葉で理解しておけば問題ありません。正規表現の書き方はいろいろあるため、おそらくいきなり網羅的に解説しても把握しきれないかと思います。

そこでこのページでは、正規表現のよくある書き方と、正規表現とセットでよく使うメソッドについて解説していきます。正規表現についてもメソッドについてもこのページで紹介する以外のものも多々ありますが、必要なときに調べていくと良いかと思います。

いきなりすべて把握しようとするよりは、サンプルコードを見つつ概要を理解していくと良いですね。

matchメソッドによるチェック

最初にもっともよく使うと思われるmatchメソッドについて解説します。このmatchメソッドは、正規表現で指定したパターンと一致するかどうかを確認するメソッドです。なんとなく使い方のイメージは付くかと思いますが、サンプルコードを紹介します。

public class Main {
     public static void main(String[] args) {

     // 検索する文字列を用意
     String str = "マサラタウン 123-4567";
     System.out.println(str.matches(".*[0-9]{3}-[0-9]{4}.*"));
     System.out.println(str.matches("[0-9]{3}-[0-9]{4}"));
     System.out.println(str.matches(".*123-4567.*"));
     System.out.println(str.matches("123-4567"));
     }
}

上記のソースコードを実行すると、以下のようにコンソール出力されます。

true
false
true
false

matchメソッドの戻り値はtrueとfalseですが、なぜ結果が分かれるのでしょうか。それは、数値の正規表現の前後に「.*」が付いているかどうかで分かれています。2番目と4番目の出力コードでは数値のみを指定しているため、前後に文字列が入ると表現からずれるためfalseとなります。

一方で、1番目と3番目の出力コードは数値の前後に「.*」が付けられています。よって、数値の前後に文字列があってもtrueになります。ちなみにマサラタウンには主人公、ライバル、オーキド博士の家しかないので、上記のような住所はないかと思います。

クラスオブジェクトを使用して正規表現チェック

次に、クラスオブジェクトを使用して正規表現チェックする方法を解説します。具体的にはPatternクラスとMatcherクラスを使用しますが、これらはインポートして使います。メソッドにつていもクラスで実装されているものを使用しています。

import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main {
     public static void main(String[] args) {
     // 検索する文字列を用意
     String str = "マサラタウン 123-4567";
     // 正規表現のパターンを作成
     Pattern p = Pattern.compile("[0-9]{3}-[0-9]{4}");
     Matcher m = p.matcher(str);
     System.out.println(m.find());
     }
}

上記のソースコードを実行すると、以下のようにコンソール出力されます。

true

まずPatternクラスのcompileメソッドの引数に正規表現を指定しています。次に、Patternクラスのmatcherメソッドの引数に正規表現と比較する文字列を指定してMatcherオブジェクトを生成しています。

最後にMatcherオブジェクトのfindメソッドを使用し、文字列を正規表現が一致するかどうかを判定しています。

一致する文字列をすべて抽出

上では一致するかどうかを判定する方法を紹介しましたが、次に一致した文字列を抽出するロジックを紹介します。サンプルコードは以下です。

import java.util.regex.Matcher;
import java.util.regex.Pattern;
     public class Main {
          public static void main(String[] args) {
          // 検索する文字列を用意
          String str = "マサラタウン 123-4567, トキワシティ000-9999";
          // 正規表現のパターンを作成
          Pattern p = Pattern.compile("[0-9]{3}-[0-9]{4}");
          Matcher m = p.matcher(str);
          while (m.find()) {
               System.out.println("一致した部分 : " + m.group());
          }
     }
}

上記のソースコードを実行すると、以下のようにコンソール出力されます。

一致した部分 : 123-4567
一致した部分 : 000-9999

while文のなかで、findメソッドで正規表現と文字列が一致したものをgroupメソッドで取得しています。

URLのチェック

正規表現の利用シーンはいろいろとありますが、現在主流のWebシステムではURLのチェックに使用する機会が多いでしょう。そこで、正規表現を用いてURLをチェックする際のサンプルコードを紹介しておきます。

import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main {
     public static void main(String[] args) {
          // 検索する文字列を用意
          String str = " https://justinjackson.ca/words_japan.html ";
          // 正規表現のパターンを作成
          Pattern p = Pattern.compile ("^https?://[ "^https?://[a-z\\.:/\\+\\-\\#\\?\\=\\&\\;\\%\\~]+$"]+$");
          Matcher m = p.matcher(str);
          System.out.println(m.find());
     }
}

上記のソースコードを実行すると、trueが返ってきます。compileメソッドの引数で\二つが複数記述されていますが、これはエスケープ処理というものです。どういうことかというと、たとえば「.」「+」などは正規表現としての意味合いもあります。

しかし上の正規表現のなかではドットやハイフンは正規表現ではなく文字列として使いたいので、\\によって正規表現としての効果を打ち消しています。つまり、ただの文字列として認識されます。このことをエスケープ処理と呼びます。

エスケープ処理の記号は、円マーク二つでもバックスラッシュ二つでもどちらでも問題ありません。文字コードの問題なので、考え方としてはパスを書くときと同じです。以上正規表現について紹介してきました。

基本事項をチェックして押さえておく必要がありますが、最初からすべての正規表現やメソッドを把握する必要はありません。概要を掴んでおけば、詳細はネット検索して実装すれば問題ないでしょう。

キャリアカウンセリングのプロとして
あなたに合った案件をご案内します。

まずはお気軽にお問い合わせください!

イメージ