Java
 Computer >> コンピューター >  >> プログラミング >> Java

Java正規表現の最短一致(レラクタント)数量詞の使い方を解説


正規表現には「貪欲な(greedy)数量詞」と「最短一致(reluctant/non-greedy)数量詞」という2種類のマッチング方法があります。

貪欲な数量詞はデフォルトの動作で、入力文字列からできるだけ多くの文字に一致しようとします(最長一致)。もし一致に失敗した場合は、末尾の1文字を手放して再度マッチングを試みます。

一方、最短一致(レラクタント)数量詞は、できるだけ少ない文字数で一致させようとします。まず入力文字列の先頭1文字だけでマッチングを試み、一致しなければ次の1文字を追加して再試行するという動作になります。

貪欲な数量詞の直後に「?」を付けると、その数量詞は最短一致(レラクタント)数量詞に変わります。主な最短一致数量詞は以下の通りです。

数量詞説明
re*?0回以上の出現に一致
re??0回または1回の出現に一致
re+?1回以上の出現に一致
re{n}?ちょうどn回の出現に一致
re{n}?n回以上の出現に一致
re{n, m}?n回以上m回以下の出現に一致

サンプルコード

次の例では、最短一致数量詞「[0-9]+?」を使って、入力された数字列から1桁ずつパターンに一致する部分を検索しています。

import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Test {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("Enter input text: ");
        String input = sc.nextLine();
        String regex = "[0-9]+?";
        // パターンオブジェクトを作成
        Pattern pattern = Pattern.compile(regex);
        // 文字列内でコンパイル済みパターンに一致する部分を検索
        Matcher matcher = pattern.matcher(input);
        while (matcher.find()) {
            System.out.print("Pattern found from " + matcher.start()+ " to " + (matcher.end()-1)+"::");
            System.out.print(matcher.group());
            System.out.println();
        }
    }
}

実行結果

Enter input text:
12345678
Pattern found from 0 to 0::1
Pattern found from 1 to 1::2
Pattern found from 2 to 2::3
Pattern found from 3 to 3::4
Pattern found from 4 to 4::5
Pattern found from 5 to 5::6
Pattern found from 6 to 6::7
Pattern found from 7 to 7::8

この実行結果から分かるように、通常の貪欲な数量詞「[0-9]+」であれば「12345678」という全体に一度で一致するところを、最短一致数量詞「[0-9]+?」では1文字ずつ個別に一致しています。これは、最短一致数量詞が常に最小限の文字数でマッチングを成立させようとするためです。連続した数字をまとめて取得したい場合は貪欲な数量詞を、必要最小限の範囲だけを取り出したい場合は最短一致数量詞を使い分けるとよいでしょう。


  1. Java正規表現のサブ式(?>re)――バックトラックしない独立パターンの解説

    Javaの正規表現におけるサブ式・メタ文字「(?>re)」は、バックトラック(後戻り)を行わない独立したパターンを表します。これは「原子グループ(atomic group)」とも呼ばれ、一度マッチに成功すると、その結果を確定してそれ以降のマッチ処理で再評価されません。バックトラックとは?通常、正規表現エンジンはパターン全体がマッチするように、部分的なマッチ結果を巻き戻して別の組み合わせを試す「バックトラック」を行います。しかし「(?>re)」で囲まれた部分は独立して扱われるため、内部でのマッチが確定した後に外側のパターンとの整合性が取れない場合でも、巻き戻しによる再試行が行われませ

  2. Javaの正規表現で文字列から数値を抽出する方法

    Javaの正規表現(Regular Expression)を使えば、文字列の中から数値だけを簡単に取り出すことができます。この記事では、実際のコード例とともに、さまざまなパターンでの数値抽出の方法を解説します。文字列を解析し、必要な情報を抜き出すスキルは、テスターにとって欠かせない能力の一つです。特にAPIテストでは、JSONやXML形式のレスポンスを解析する場面が多く、正規表現の知識が大いに役立ちます。以下では、Javaの正規表現を使って文字列から数字・数値を抽出する具体的な例を紹介します。文字列からすべての数値を抽出するimport java.util.regex.Matcher; imp