ホームページ  >  記事  >  バックエンド開発  >  php — PCRE正規表現のワンタイムサブグループ化

php — PCRE正規表現のワンタイムサブグループ化

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

最大数量子と最小数量子の両方の制限がある重複の場合、一致が失敗した後、別の回数繰り返して再評価され、パターンが一致するかどうかが確認されます。 パターンの作成者が実装に問題がないことを確実に知っている場合は、一致の動作を変更するか、以前の一致を失敗させることで、この動作を防止すると便利です。

パターン d+foo がターゲット行 123456bar に適用される場合の例を考えてみましょう。

6 桁のマッチング後に "foo" とのマッチングに失敗する 通常の動作では、マッチャーは d+ を 5 桁のみにマッチングさせようとします。 4 つの数値のみに一致し、最終的に失敗する前に順番に試行されます。 ワンショット サブグループには、パターンの一部が一度一致すると再評価されないという特別な意味があり、最初に「foo」との一致に失敗した直後にマッチャーが失敗する可能性があります。構文記号は、(?>d+)bar など、(?> で始まる別の特殊な種類のかっこです。

この種類のかっこは、パターンの一部に「ロック」を提供し、パターンにパターンが含まれないようにします。 future パターン内の後方トレースバックはここで失敗し、他の作業は通常どおり続行されます。つまり、ターゲット文字列内の現在の一致点がアンカー ポイントである場合、このタイプの一致した文字列はスタンドアロンと同等です。

簡単に言えば、ワンタイム サブグループは、一致する文字をできるだけ多く消費します。したがって、d+ と d+? は、他の部分が一致するように調整します。のパターン一致ですが、(?>d+) は数字のシーケンス全体にのみ一致します。

この (文法的な) 構造には、任意の複雑な文字を含めることができ、1 回限りのサブグループを埋め込むこともできます。ターゲット文字列の末尾で有効な一致を指定するために先読みアサーションとともに使用されます。 abcd$ などの単純なパターンが、左から処理された長い文字列に適用される場合、PCRE はそれぞれの " を検索します。ターゲット内の a" を検索し、パターンの残りの部分がすぐに一致するかどうかを確認します。パターンが ^.*abcd$ の場合、最初の .* が最初に文字列全体と一致しますが、失敗すると (一致しないため)続いて "a")、すべての一致をバックトラックして、最後の文字、最後から 2 番目の文字などを吐き出し、文字列全体で右から左に "a" を検索します。そのため、これはできません。ただし、パターンが ^(?>.*)(?<=abcd) と記述されている場合、.* 部分はバックトラックされず、述語は文字列全体にのみ一致します。長い文字列の場合、無限に繰り返される要素を含むサブグループが含まれる場合、このパターンは処理時間の大幅なパフォーマンスの向上をもたらします。その中では、1 回限りのサブグループを使用することが、時間のかかる失敗を回避する唯一の方法です。パターン (D+|)*[!?] は、無制限の数の非一致と一致します。 <> または ? で囲まれた数字。ただし、「aaaaaaaaaaaaaaaaaaaaaaaaaa」に適用すると、非常に時間がかかります。この文字列は両方の繰り返しルールに使用でき、両方の繰り返しルールで試行する必要があるためです (例の最後では、PCRE と Perl のため、単一文字の代わりに [!?] が使用されています。すべてが、次の場合に高速エラー レポートを最適化します)。パターンは 1 文字で終わります。 これらは、一致する必要がある最後の 1 文字を追跡し、文字列内に出現しない場合はすぐにエラーを報告します。 ) モードを ((?>D+)|)*[!?] に変更すると、すぐにエラーが発生します。 (注釈: ここで指定したモードでは、対象の文字列が長くなると、消費時間が急激に増加するため、使用には注意してください。)

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