工業製造
産業用モノのインターネット | 工業材料 | 機器のメンテナンスと修理 | 産業プログラミング |
home  MfgRobots >> 工業製造 >  >> Industrial programming >> Java

Java正規表現: java.util.regexでパターンマッチングをマスターする

Javaはjava.util.regexパッケージを提供し、正規表現を用いたパターンマッチングを実現します。Javaの正規表現はPerlプログラミング言語のものと非常に似ており、学習も容易です。

正規表現とは

正規表現とは、パターンに保持される特殊な構文を用いて、他の文字列や文字列のセットをマッチングまたは検索するための、特殊な文字シーケンスです。テキストやデータの検索、編集、操作に利用できます。

java.util.regexの主要クラス

java.util.regexパッケージは主に以下の3つのクラスで構成されます。

キャプチャグループ

キャプチャグループは、複数の文字を単一のユニットとして扱う仕組みです。グループ化したい文字を括弧で囲むことで作成します。例えば、正規表現(dog)は「d」「o」「g」を含む単一のグループを作成します。

キャプチャグループは、左から右へ開き括弧を数えることで番号付けされます。式((A)(B(C)))には、例えば以下の4つのグループがあります。

式に存在するグループ数を知るには、MatcherオブジェクトのgroupCount()メソッドを呼び出します。このメソッドは、Matcherのパターンに存在するキャプチャグループの数をintで返します。

また、グループ0という特殊なグループが常に存在し、これは式全体を表します。このグループはgroupCount()の合計には含まれません。

例: 英数字文字列から数字列を抽出

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexMatches {
    public static void main(String args[]) {
        // パターンを検索する対象文字列
        String line = "This order was placed for QT3000! OK?";
        String pattern = "(.*)(\\d+)(.*)";

        // Patternオブジェクトを作成
        Pattern r = Pattern.compile(pattern);
        // Matcherオブジェクトを作成
        Matcher m = r.matcher(line);

        if (m.find()) {
            System.out.println("Found value: " + m.group(0));
            System.out.println("Found value: " + m.group(1));
            System.out.println("Found value: " + m.group(2));
        } else {
            System.out.println("NO MATCH");
        }
    }
}

実行結果

Found value: This order was placed for QT3000! OK?
Found value: This order was placed for QT300
Found value: 0

正規表現の構文

Javaで利用可能な正規表現メタキャラクタ構文を以下の表にまとめます。

部分配列一致する内容
^行の先頭に一致
$行の末尾に一致
.改行を除く任意の1文字に一致。mオプション使用時は改行も含む
[...]括弧内の任意の1文字に一致
[^...]括弧内にない任意の1文字に一致
\A文字列全体の先頭
\z文字列全体の末尾
\Z文字列全体の末尾(許容される最終行終端文字を除く)
re*直前の式の0回以上の繰り返し
re+直前のものの1回以上の繰り返し
re?直前の式の0回または1回の出現
re{ n}直前の式のちょうどn回の出現
re{ n,}直前の式のn回以上の出現
re{ n, m}直前の式のn回以上m回以下の出現
a| baまたはbに一致
(re)正規表現をグループ化し、マッチしたテキストを記憶
(?: re)正規表現をグループ化するが、マッチしたテキストを記憶しない
(?> re)バックトラックなしで独立したパターンに一致
\w単語構成文字に一致
\W非単語構成文字に一致
\s空白文字に一致。[\t\n\r\f]と同等
\S非空白文字に一致
\d数字に一致。[0-9]と同等
\D非数字に一致
\A文字列の先頭に一致
\Z文字列の末尾に一致。改行があればその直前
\z文字列の末尾に一致
\G前回のマッチが終了した位置
\nキャプチャグループ番号「n」への後方参照
\b括弧の外では単語境界、中ではバックスペース(0x08)に一致
\B非単語境界に一致
\n, \t, etc.改行、キャリッジリターン、タブ等に一致
\Q\Eまでのすべての文字をエスケープ(クォート)
\E\Qで始まったクォートを終了

Matcherクラスのメソッド

インデックスメソッド

入力文字列においてマッチが見つかった正確な位置を示すインデックス値を提供します。

No.メソッドと説明
1public int start() - 前回のマッチの開始インデックスを返す
2public int start(int group) - 前回のマッチ操作で指定グループが捕捉した部分列の開始インデックスを返す
3public int end() - 最後にマッチした文字の次のオフセットを返す
4public int end(int group) - 前回のマッチ操作で指定グループが捕捉した部分列の最後の文字の次のオフセットを返す

検査メソッド

入力文字列を検査し、パターンが見つかるかどうかをbooleanで返します。

No.メソッドと説明
1public boolean lookingAt() - リージョンの先頭から入力シーケンスをパターンにマッチさせようとする
2public boolean find() - パターンにマッチする入力シーケンスの次の部分列を検索しようとする
3public boolean find(int start) - このMatcherをリセットし、指定インデックスから次の部分列を検索しようとする
4public boolean matches() - リージョン全体をパターンにマッチさせようとする

置換メソッド

入力文字列内のテキスト置換に便利なメソッドです。

No.メソッドと説明
1public Matcher appendReplacement(StringBuffer sb, String replacement) - 非終端の追加と置換ステップを実装
2public StringBuffer appendTail(StringBuffer sb) - 終端の追加と置換ステップを実装
3public String replaceAll(String replacement) - パターンにマッチする入力シーケンスのすべての部分列を指定置換文字列で置き換え
4public String replaceFirst(String replacement) - パターンにマッチする最初の部分列を置換
5public static String quoteReplacement(String s) - 指定文字列のリテラル置換Stringを返す。MatcherクラスのappendReplacementメソッドでリテラル置換sとして機能するStringを生成

startメソッドとendメソッドの例

入力文字列内で単語「cat」が出現する回数を数える例です。

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexMatches {
    private static final String REGEX = "\\bcat\\b";
    private static final String INPUT = "cat cat cat cattie cat";

    public static void main(String args[]) {
        Pattern p = Pattern.compile(REGEX);
        Matcher m = p.matcher(INPUT);
        int count = 0;

        while (m.find()) {
            count++;
            System.out.println("Match number " + count);
            System.out.println("start(): " + m.start());
            System.out.println("end(): " + m.end());
        }
    }
}

実行結果

Match number 1 start(): 0 end(): 3
Match number 2 start(): 4 end(): 7
Match number 3 start(): 8 end(): 11
Match number 4 start(): 19 end(): 22

この例では単語境界を使用して、「c」「a」「t」がより長い単語の部分文字列でないことを保証しています。また、入力文字列のどこでマッチが発生したかについての有用な情報も提供されます。

startメソッドは、前回のマッチ操作で指定グループが捕捉した部分列の開始インデックスを返し、endは最後にマッチした文字のインデックスに1を加えた値を返します。

matchesメソッドとlookingAtメソッド

両メソッドとも入力シーケンスをパターンにマッチさせようとしますが、matchesは入力シーケンス全体のマッチを要求するのに対し、lookingAtは要求しません。両者は常に入力文字列の先頭から開始します。

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexMatches {
    private static final String REGEX = "foo";
    private static final String INPUT = "fooooooooooooooooo";
    private static Pattern pattern;
    private static Matcher matcher;

    public static void main(String args[]) {
        pattern = Pattern.compile(REGEX);
        matcher = pattern.matcher(INPUT);
        System.out.println("Current REGEX is: " + REGEX);
        System.out.println("Current INPUT is: " + INPUT);
        System.out.println("lookingAt(): " + matcher.lookingAt());
        System.out.println("matches(): " + matcher.matches());
    }
}

実行結果

Current REGEX is: foo
Current INPUT is: fooooooooooooooooo
lookingAt(): true
matches(): false

replaceFirstメソッドとreplaceAllメソッド

指定された正規表現にマッチするテキストを置換します。名前の通り、replaceFirstは最初の出現を、replaceAllはすべての出現を置換します。

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexMatches {
    private static String REGEX = "dog";
    private static String INPUT = "The dog says meow. " + "All dogs say meow.";
    private static String REPLACE = "cat";

    public static void main(String[] args) {
        Pattern p = Pattern.compile(REGEX);
        Matcher m = p.matcher(INPUT);
        INPUT = m.replaceAll(REPLACE);
        System.out.println(INPUT);
    }
}

実行結果

The cat says meow. All cats say meow.

appendReplacementメソッドとappendTailメソッド

Matcherクラスはテキスト置換用にappendReplacementとappendTailメソッドも提供します。

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexMatches {
    private static String REGEX = "a*b";
    private static String INPUT = "aabfooaabfooabfoob";
    private static String REPLACE = "-";

    public static void main(String[] args) {
        Pattern p = Pattern.compile(REGEX);
        Matcher m = p.matcher(INPUT);
        StringBuffer sb = new StringBuffer();

        while (m.find()) {
            m.appendReplacement(sb, REPLACE);
        }
        m.appendTail(sb);
        System.out.println(sb.toString());
    }
}

実行結果

-foo-foo-foo-

PatternSyntaxExceptionクラスのメソッド

PatternSyntaxExceptionは正規表現パターンの構文エラーを示す非チェック例外です。このクラスは以下のメソッドを提供し、何が間違っていたかを特定するのに役立ちます。

No.メソッドと説明
1public String getDescription() - エラーの説明を取得
2public int getIndex() - エラーのインデックスを取得
3public String getPattern() - エラーのある正規表現パターンを取得
4public String getMessage() - 構文エラーの説明とそのインデックス、エラーのあるパターン、パターン内のエラーインデックスの視覚的表示を含む複数行の文字列を返す

Java

  1. C# の式、文、ブロック:実践例で徹底理解
  2. Java演算子をマスター:種類、構文、実践例
  3. Javaの式、文、ブロックを理解する
  4. Javaコメント:種類、使い方、ベストプラクティス
  5. Java拡張forループをマスター:構文、例、ベストプラクティス
  6. Java文字列をマスター:生成、メソッド、ベストプラクティス
  7. Javaインターフェース完全ガイド:概念、実装、ベストプラクティス
  8. Javaのtry-with-resourcesをマスターする:自動リソース管理の仕組みと活用法
  9. Javaアノテーション完全ガイド:種類、配置場所、実践例
  10. Javaアサーション完全ガイド:バグ早期発見とコード信頼性の向上
  11. Javaラムダ式完全ガイド:基礎からStream APIまで