ホームページ  >  記事  >  バックエンド開発  >  PHP の通常の失敗 - 最大バックトラッキング (pcre.backtrack_limit)/再帰制限

PHP の通常の失敗 - 最大バックトラッキング (pcre.backtrack_limit)/再帰制限

WBOY
WBOYオリジナル
2016-06-13 12:50:261013ブラウズ

PHP 正規表現のエラー - 最大バックトラッキング (pcre.backtrack_limit)/再帰制限

昨日、同僚が通常の定期収集プログラムに取り組んでいて、奇妙な現象を発見しました。何気なく書いているのですが、サーバーにアップロードしてみると、どうやって正規表現を書いても一致しないことが分かりました。長期間調整しても効果がなかったので、諦めていませんか?それから...私は負けるつもりはありませんでした...夕食後、パソコンを立ち上げて、正規表現のルールについて何気なくブログを書いたり、正規表現の書き方などについて話し続けました。ようやく落ち着いて分析してみました。

同僚と私はコンピューターに WAMP をインストールしていますが、PHP のバージョンは 5.3.x で、サーバーの PHP のバージョンは 5.2.x です。これが問題なのでしょうか? pcre 関数 - preg_match_all、いいですね。preg_last_error 関数があることがわかりました。それを開いて調べたところ、返されたエラーは PREG_BACKTRACK_LIMIT_ERROR でした。問題があるため、コードの先頭に追加しました。結果は正常にキャプチャされます。マニュアルを振り返ってみると、次のような紹介文がありました:


最後に、オンラインでいくつかの情報を確認しました。ブロガーの 1 人が非常に詳細な情報を書いていました。関連するコンテンツと説明をいくつか示します。

PHP の拡張子 pcre には 2 つの設定項目が用意されています。


1 pcre.backtrack_limit //バックトラックの最大数
2 pcre.recursion_limit //ネストの最大数


デフォルトの backtarck_limit は 100000 (100,000) です。
さて、この問題の原因を解明するには、「バックトラッキング」とは何かが鍵となります。
この正規表現は、非貪欲モードを使用します。非貪欲パターン マッチングの原理は、単純に、一致または不一致の場合に、不一致を優先して記録し、一致制御を引き継ぎます。正規表現文字の次の一致。その後の一致が失敗した場合は、戻って一致します。

例: ソース文字列: aaab 正規: .*?
マッチング処理が開始されると、まず「.*?」がマッチング制御を取得します。これは非貪欲モードであるため、最初はマッチングせず、次にマッチングした文字「b」にマッチング制御を渡します。ソース文字列の位置 1 でエラー (「a」) が発生したため、バックトラックして一致する制御を「.*?」に戻します。この時点で、「.*?」は文字「a」に一致し、制御を に渡します。もう一度「b」、というようにして、最終的に一致する結果が得られ、このプロセスで合計 3 回のバックトラッキングが発生しました。



最後に、まだ言いたいことがあります

1. PHP 5.2 以降では、次の機能が提供されます。 int preg_last_error (void) 最後の PCRE 正規表現実行のエラー コードを返します。

この関数の戻り値がゼロでない場合は、特に記事の例ではエラー (PREG_BACKTRACK_LIMIT_ERROR) が返されたことを意味します。 2. 非貪欲モードではバックトラッキングが多すぎるため、必然的にパフォーマンスの問題が発生します。この問題は、特に大量のデータを扱うテキスト処理を行う場合に、通常のルールを適切に記述することで回避できます。慎重に設計しないと、非常に困難になります。また、パフォーマンスを考慮して、代わりに文字列処理を使用することをお勧めします。



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