概要: このチュートリアルでは、貪欲な量指定子とその仕組みについて学習します。
すべての量指定子は、デフォルトで貪欲モードで動作します。これは、量指定子が先行要素にできるだけ多く一致することを意味します。
次の例は、貪欲な量指定子の動作を示しています。
貪欲な量指定子の例
ボタン要素を表すHTML文字列があるとします。
const button = '<button type="submit" class="btn">Send</button>';
Code language: JavaScript (javascript)
そして、submit
や btn
のように、二重引用符(""
)で囲まれたテキストを一致させたいとします。
そのためには、二重引用符(")、ドット(.
)文字クラス、および(+
)量指定子を使用して、次のパターンを構築します。
/".+"/g
Code 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)
この問題を解決するには、量指定子(+
)に、貪欲モードではなく非貪欲(または遅延)モードを使用するように指示する必要があります。そのためには、量指定子の後に疑問符(?
)を追加します。
/".+?"/g
Code 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)
まとめ
- 量指定子はデフォルトで貪欲モードを使用します。
- 貪欲な量指定子は、先行要素にできるだけ多く一致します。