正規表現: グリーディマッチ

概要: このチュートリアルでは、貪欲な量指定子とその仕組みについて学習します。

すべての量指定子は、デフォルトで貪欲モードで動作します。これは、量指定子が先行要素にできるだけ多く一致することを意味します。

次の例は、貪欲な量指定子の動作を示しています。

貪欲な量指定子の例

ボタン要素を表すHTML文字列があるとします。

const button = '<button type="submit" class="btn">Send</button>';Code language: JavaScript (javascript)

そして、submitbtn のように、二重引用符("")で囲まれたテキストを一致させたいとします。

そのためには、二重引用符(")、ドット(.文字クラス、および(+量指定子を使用して、次のパターンを構築します。

/".+"/gCode language: JavaScript (javascript)

このパターンは、次のことを意味します。

  • "" で始まります
  • . は改行以外の任意の文字に一致します
  • + は先行する文字に1回以上一致します
  • "" で終わります
  • g フラグはすべての一致を返します

以下は、match() メソッドを使用して、文字列 s をパターンと照合します。

const s = '<button type="submit" class="btn">Send</button>';
const pattern = /".+"/g;

const result = s.match(pattern);
console.log(result);Code language: JavaScript (javascript)

出力

['"submit" class="btn"']Code language: JavaScript (javascript)

submit” と btn の代わりに、'"submit" class="btn"' が返されます。

これは、貪欲モードでは、量指定子(+)が先行要素(".)にできるだけ多く一致しようとするためです。

貪欲な量指定子の仕組み

まず、正規表現エンジンは文字列 s の最初の文字から照合を開始します。

次に、最初の文字 < は引用符(")と一致しないため、正規表現エンジンは最初の引用符(")が見つかるまで次の文字の照合を続けます。

次に、正規表現エンジンは文字列を正規表現の次のルール .+ と照合します。

.+ ルールは1つ以上の文字に一致するため、正規表現エンジンは文字列の末尾に達するまで文字に一致します。

その後、正規表現エンジンは正規表現の最後のルールである引用符(")をチェックします。しかし、文字列の末尾にすでに達しているため、一致する文字はもうありません。これは、正規表現エンジンが行き過ぎて貪欲すぎることを意味します。

最後に、正規表現エンジンは文字列の末尾から戻って引用符(")を探します。この手順は、しばしばバックトラッキングと呼ばれます。

その結果、一致は次の部分文字列になりますが、これは期待どおりのものではない可能性があります。

"submit" class="btn"Code language: JavaScript (javascript)

この問題を解決するには、量指定子(+)に、貪欲モードではなく非貪欲(または遅延)モードを使用するように指示する必要があります。そのためには、量指定子の後に疑問符(?)を追加します。

/".+?"/gCode language: JavaScript (javascript)

次のスクリプトは、期待される結果を返します。

const s = '<button type="submit" class="btn">Send</button>';
const pattern = /".+?"/g;

const result = s.match(pattern)
console.log(result);Code language: JavaScript (javascript)

出力

['"submit"', '"btn"']Code language: JavaScript (javascript)

まとめ

  • 量指定子はデフォルトで貪欲モードを使用します。
  • 貪欲な量指定子は、先行要素にできるだけ多く一致します。
このチュートリアルは役に立ちましたか?