web-dev-qa-db-ja.com

PHP ereg vs. preg

PHP regexライブラリで、eregとpregのどちらかを選択できることに気づきました。違いは何ですか?一方が他方よりも高速である場合、遅い方が非推奨にならないのはなぜですか?

どちらか一方を使用する方が良い状況はありますか?

38
Evernoob

Php.net/eregにアクセスすると、次のように表示されます。

警告

この関数はPHP 5.3.0で非推奨になり、PHP 6.0.0で削除されました。この機能に依存することは強くお勧めしません。

ページをもう少し下に移動すると、次のようになります。

注:Perl互換の正規表現構文を使用するpreg_match()は、多くの場合、ereg()のより高速な代替手段です。

私の強調に注意してください。

42
Sampson

pregはPerl互換の正規表現ライブラリです
eregはPOSIX準拠の正規表現ライブラリです

それらはわずかに異なる構文を持ち、pregは場合によってはわずかに高速です。 eregは非推奨になっている(そしてphp6で削除されている)ので、使用することはお勧めしません。

19
Yacoby

どちらがより速く、より良いかについては多くの議論があります。

いつかPHP6に進むことを計画している場合は、決定が下されます。さもないと:

一般的なコンセンサスは、PCREの方が優れたソリューションであるということですが、トラフィックの多い特定のページがあり、PHP6が必要ない場合は、テストする価値があるかもしれません。たとえば、PHP手動コメントから:

Perl検索のPHPでのPOSIX正規表現の非推奨は、事前に作成された部屋と壁のある家の代わりに木の板とレンガを使用するようなものです。確かに、一部のパーツを組み合わせて組み合わせることができる場合がありますが、すべてのピースを目の前に配置すると、変更がはるかに簡単になります。

PCREはPOSIXREよりも高速ですか?常にではない。ここCynergiでの最近の検索エンジンプロジェクトでは、データの処理に3分かかるいくつかのかわいいereg_replace()関数を含む単純なループがありました。その10行のループを100行の手書きコードに変更して置き換えたところ、同じデータを処理するのに10秒かかりました。これにより、場合によっては非常に遅い正規表現になり得ることに目を向けました。最近、Perl互換の正規表現(PCRE)を調べることにしました。ほとんどのページはPCREがPOSIXよりも高速であると主張していますが、そうでないことを主張するページもあります。私は自分のベンチマークを決めました。最初のいくつかのテストでPCREの方が高速であることが確認されましたが、結果は他のテストとは少し異なっていたため、8000行の安全な(高速な)WebメールプロジェクトでのRE使用のすべてのケースをベンチマークすることにしました。 Cynergiをチェックしてください。結果?決定的ではありません! PCRE areの方が速い場合もありますが(100倍以上速い場合もあります!)、POSIX REの方が速い場合もあります(2倍)。私はまだどちらが速いかについてのルールを見つけなければなりません。関数を頻繁に繰り返したときに表示されるのは、検索データのサイズ、一致したデータの量、または「REコンパイル時間」だけではありません。一方は常にもう一方よりも高速です。しかし、ここではパターンが見つかりませんでした。しかし、正直なところ、私もソースコードを調べて問題を分析するのに時間をかけませんでした。ただし、いくつか例を挙げます。 POSIX RE([0-9] {4})/([0-9] {2})/([0-9] {2})[^ 0-9] +([0-9] {2 }):( [0-9] {2}):( [0-9] {2})POSIXでは、PCREに変換した場合よりも30%高速です(\ dと\ Dを使用し、貪欲でないマッチングを使用した場合でも) )。一方、同様にPCREの複雑なパターン/ [0-9] {1,2} [\ t] + [a-zA-Z] {3} [\ t] + [0-9] {4} [\t] + [0-9] {1,2}:[0-9] {1,2}(:[0-9] {1,2})?[\ t] + [+-] [0 -9] {4} /は、PCREではPOSIXREよりも2.5倍高速です。 ereg_replace( "[^ a-zA-Z0-9-] +"、 ""、$ m);のような単純な置換パターン。 POSIXREではPCREより2倍高速です。そして、(^ |\n |\r)begin-base64 [\ t] + [0-7] {3,4} [\ t] + ......のようなPOSIXREパターンがあるため、再び混乱します。 POSIX REの2倍高速ですが、大文字と小文字を区別しないPCRE/^ Received [\ t] *:[\ t] by [\ t] +([^\t] +)[\ t]/i POSIX REバージョンよりも30倍高速です!大文字と小文字の区別に関しては、これまでのところPCREが最良の選択肢のようですが、ereg/eregiからは非常に奇妙な動作が見つかりました。非常に単純なPOSIXRE(^ |\r |\n)mime-version [\ t]:eregi()は3.60秒(テストベンチマークの数値)を要しましたが、対応するPCREは0.16秒かかりました!しかし、ereg()(大文字と小文字を区別する)を使用した場合、POSIX RE時間は0.08秒に短縮されました!そこで、さらに調査しました。 POSIXRE自体で大文字と小文字を区別しないようにしました。私はこれまでに到達しました:(^ |\r |\n)[mM] [iI] [mM] [eE] -vers [iI] [oO] [nN] [\ t] *:このバージョンも0.08かかりましたs。しかし、変更されていない「v」、「e」、「r」、または「s」の文字のいずれかに同じルールを適用しようとすると、時間は3.60秒のマークに戻り、徐々にではなく、すぐに戻ります。そう!テストデータには、「vers」、他の「mime」の単語、またはPOSIXパーサーを混乱させる可能性のある「ion」が含まれていなかったため、途方に暮れています。結論:常にPCRE/POSIX REのベンチマークを実行して、最速のものを見つけてください。テストは、コマンドラインからPHP 5.1.2、Windowsで実行されました。PedroFreirecynergi.com

5
SamGoody

EregはPHP 5.3で非推奨ですが、mb_ereg *関数は非推奨です。これの主な理由は、PHP6がすべてのMB/Unicodeサポートを再構築しているため、古い「通常の」eregであると考えています。 mb_eregはより新しく/より良くなるので、メソッドは役に立ちません。

速度に関する質問には答えられないことは知っていますが、POSIXとPCREの両方を引き続き使用できます。

4
Percy

ええと、eregとその派生関数(ereg_matchなど)はphp5で非推奨になり、php6で削除されるので、代わりにpregファミリーを使用するのがおそらく最善です。

pregはPerlスタイルの正規表現用であり、eregは標準のPOSIX正規表現です。

3
Amber