ホームページ  >  記事  >  バックエンド開発  >  php — PCRE 正規表現の繰り返し/量指定子

php — PCRE 正規表現の繰り返し/量指定子

伊谢尔伦
伊谢尔伦オリジナル
2016-11-21 17:18:221229ブラウズ

繰り返しの数は、次の要素に続く量指定子によって指定されます:

エスケープされた

メタ文字である単一の文字。

文字クラス

後方参照 (次のセクションを参照)

サブグループ (アサーションでない場合)

一般的な繰り返し数量子は、中括弧で囲まれた最小値と最大値の一致の数を指定します。 数値、で区切られた 2 つの数値カンマ。 両方の数値は 65536 未満である必要があり、最初の数値は 2 番目の数値以下である必要があります。 たとえば、z{2,4} は「zz」、「zzz」、「zzzz」に一致します。 単一の閉じ中括弧は特殊文字ではありません。 2 番目の数値が省略されてもカンマが存在する場合は、上限がないことを意味します。2 番目の数値とカンマの両方が省略された場合、数量指定子は一致の特定の数を制限します。 たとえば、[aeiou]{3,} は少なくとも 3 つの連続する母音と一致しますが、それ以上の母音と一致することもありますが、d{8} は 8 つの数字のみと一致します。 左中括弧が量指定子の使用を許可しない位置にある場合、または量指定子の構文と一致しない場合、それは通常の文字とみなされ、元のテキスト内でそれ自体が一致します。 たとえば、{,6} は量指定子ではないため、元のテキストに従って 4 つの文字「{,6}」と一致します。

量指定子 {0} は許可されていますが、それによって引き起こされる動作は、先行する項と量指定子が存在しないというものです。

利便性 (および歴史的な互換性) のため、最も一般的に使用される 3 つの量指定子には 1 文字の略語が付けられています。

単一文字数量子

* {0,} に相当

+ {1,} に相当

? {0,1} に相当

の後には、どの文字にも一致しないサブパターンが続きますキャップなしの無限ループを構築するために 0 個以上の文字と一致する量指定子。 例: (a?)*

perl および pcre の以前のバージョンでは、このモードのコンパイル時にエラーが発生します。ただし、場合によってはこれが役立つ可能性があるため、このパターンは受け入れられるようになりましたが、サブパターンの繰り返しがどの文字にも一致しない場合、ループは強制的に終了します。

デフォルトでは、量指定子は「貪欲」です。つまり、パターン マッチングが失敗することなく、できるだけ多くの文字 (許可される最大一致数まで) と一致します。 この問題の典型的な例は、C のコメントを照合しようとすることです。 /* と */ の間にあるものはすべてコメントとみなされ、個々の * と / はコメントの途中に使用できます。 C のコメントを照合する試みの 1 つは、パターン /*.**/ を使用することです。このパターンを文字列「/* 最初のコメント */ ではなくコメント /* 2 番目のコメント */」に適用すると、間違った結果と照合されます。これは文字列全体です。これは、できるだけ多くの文字と一致しようとする量指定子の貪欲な性質によるものです。

ただし、量指定子の後に ? (疑問符) トークンが続くと、遅延 (非貪欲) モードになり、可能な限り一致するのではなく、可能な限り一致しないようになります。 したがって、パターン /*.*?*/ は C のコメント マッチングで正しく機能します。 各数量詞自体の意味は変わりませんが、? の追加により優先一致の数が変わります。 この ? の使用と量指定子としての使用を混同しないでください。これには 2 つの用途があるため、場合によっては量指定子が含まれることがあります。たとえば、d??d は数値と一致する傾向がありますが、同時に、パターン マッチング全体の目的を達成する場合にも使用できます。 2 つの数値の一致を受け入れます。注釈: パターン wd??dw を例にとると、文字列「a33a」の場合、d?? は非グリーディですが、グリーディを使用するとパターン全体が一致しなくなるため、最終的には次の数値が選択されます。一致します。

PCRE_UNGREEDY オプションが設定されている場合 (Perl では使用できないオプション)、量指定子はデフォルトで非貪欲になります。ただし、単一の量指定子の後に ? を付けると貪欲にすることができます。つまり、PCRE_UNGREEDY オプションは、貪欲なデフォルトの動作を逆転させます。

「+」の後に続く数量詞は「所有」を意味します。可能な限り多くの文字を使用し、その背後にある他のパターンには注意を払いません。たとえば、 .*abc は "aabc" に一致しますが、 .*+abc は一致しません。これは、 .*+ が文字列全体を使用するためです。以下の残りのパターンは一致しません。 PHP 4.3.3 以降、所有者 (+) を使用して量指定子を変更し、速度を向上させることができます。

サブグループが 1 より大きい最小数量または最大数量制限を持つ量指定子によって修飾される場合、最小数量または最大数量に比例して、コンパイル済みモードにより多くのストレージが必要になります。

パターンが .* または .{0,} で始まり、PCRE_DOTALL オプションがオンになっている場合 (Perl の /s に相当)、これにより . が改行に一致することが許可され、パターンは暗黙的に固定されます。ターゲット文字列内の次の文字位置が試行されるため、最初の後にすべての一致が再試行されることはありません。 PCRE は、このパターンを A と同じように扱います。 ターゲット文字列に改行が含まれていないことがわかっている場合にパターンが .* で始まるときにこの最適化を実現するには、PCRE_DOTALL を設定するか、代わりに ^ を使用してアンカーを明示的に指定する価値があります。

注釈: ここでの最適化とは、パターンが一致しなかった場合、たとえば、PCRE_DOTALL が設定されておらず、ターゲット文字列の最初の文字が改行文字である場合、次の位置を見つけるために遡ることはしないことを意味します。パターンは最初の文字を試して一致しないことが判明した場合、2 番目の文字位置から始まるパターンを使用して再試行します。 PCRE_DOTALL を使用すると、必ず一致します... 同様に、^ または /A を使用する場合、パターンが一致しない場合は、ターゲット文字列の次の位置でパターン全体を再度開始することなく、直接終了できるという制限があります。マッチ。

キャプチャされたサブグループが繰り返される場合、キャプチャされたサブグループの結果は、最後の反復でキャプチャされた値になります。たとえば、(tweedle[dume]{3}s*)+ は文字列「tweedledum tweedledee」と一致し、取得されるサブグループのキャプチャ結果は「tweedledee」になります。ただし、ネストされたキャプチャ サブグループの場合、対応するキャプチャ値は前の反復で設定される可能性があります。たとえば、/(a|(b))+/ は文字列「aba」と一致し、2 番目にキャプチャされたサブグループの結果は「b」になります。翻訳者注: 「ただし」以降の部分がわからない場合は、例を使用して、b が 2 番目のサブグループの最後にキャプチャされた結果であることを説明しましょう。したがって、2 番目のサブグループの最終結果は b となり、これは次の条件と一致します。 「ただし」の前に記載されているルール。


声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。