Java正規表現の所有格数量詞(Possessive Quantifier)とは?貪欲数量詞との違いを解説
Javaの正規表現には、貪欲数量詞(Greedy Quantifier)、控えめ数量詞(Reluctant Quantifier)、そして所有格数量詞(Possessive Quantifier)の3種類があります。この記事では、その中でも特に「所有格数量詞」について詳しく解説します。
貪欲数量詞と所有格数量詞の違い
貪欲数量詞はデフォルトで使用される数量詞です。入力文字列から可能な限り長くマッチしようとし(最長一致)、マッチに失敗した場合は末尾の文字を1つ外して再度マッチを試みます。この動作をバックトラック(巻き戻し)と呼びます。
一方、所有格数量詞も貪欲数量詞と同様に、最初にできるだけ多くの文字にマッチしようとします。しかし、マッチに失敗した場合、貪欲数量詞とは異なりバックトラックを行いません。これにより、不要な再試行が省かれ、パフォーマンスが向上するケースがあります。
所有格数量詞の書き方
貪欲数量詞の直後に「+」を付けることで、所有格数量詞になります。主な所有格数量詞の一覧は以下の通りです。
| 数量詞 | 説明 |
|---|---|
| re*+ | 0回以上の出現にマッチします。 |
| re?+ | 0回または1回の出現にマッチします。 |
| re++ | 1回以上の出現にマッチします。 |
| re{n}+ | ちょうどn回の出現にマッチします。 |
| re{n, m}+ | n回以上、m回以下の出現にマッチします。 |
サンプルコード
次の例では、所有格数量詞 [0-9]++ を使って、入力された文字列から連続する数字を抽出しています。
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(matcher.group());
System.out.println();
}
}
}
実行結果
Enter input text: 45678 45678
この例では、入力文字列「45678」全体が1つの数字列として検出され、そのまま出力されています。所有格数量詞はバックトラックしないため、数字の連続を一括して効率的にマッチできます。
まとめ
- 所有格数量詞は、貪欲数量詞の後に「+」を付けて表記する。
- 最大限のマッチを試みる点は貪欲数量詞と同じだが、失敗時にバックトラックしないのが特徴。
- バックトラックが不要なパターンでは、処理速度の向上が期待できる。
-
Java正規表現のサブ表現(?:re)とは?非キャプチャグループの基本とサンプルコード
Javaの正規表現におけるサブ表現(メタ文字)「(?: re)」は、正規表現をグループ化するための構文です。通常のグループ「(re)」と異なり、マッチしたテキストを記憶(キャプチャ)しないため、「非キャプチャグループ」と呼ばれます。 (?:re) の特徴 「(?:re)」を使うと、複数の要素をひとつのまとまりとして扱えますが、後方参照や group() メソッドでの取得対象にはなりません。マッチの判定だけが必要で、キャプチャした文字列を後から利用しない場合に、メモリの無駄を省き、パターンをすっきり記述できるのがメリットです。 サンプルコード 以下は、ユーザーから入力された文字列に対して「(?:
-
【Java】正規表現のメタ文字\B(非単語境界)の使い方をサンプルコードで解説
Javaの正規表現におけるメタ文字「\B」は、単語境界以外の位置(非単語境界)にマッチします。この記事では、\Bの基本的な意味と、サンプルコードによる具体的な動作をわかりやすく解説します。 メタ文字\Bとは 正規表現の\bは「単語境界」、すなわち単語文字([a-zA-Z_0-9])とそれ以外の文字の境目にある位置にマッチします。\Bはその逆で、次のような単語境界になっていない位置にマッチします。 単語文字と単語文字の間(例:「ab」の「a」と「b」の間) 非単語文字と非単語文字の間(例:「!@」の「!」と「@」の間) また、\Bはゼロ幅アサーションと呼ばれる種類のパターンのため、マッチし