38

PHP 正規表現ライブラリで、ereg と preg のどちらかを選択できることに気付きました。違いはなんですか?一方が他方より速いのですか?もしそうなら、遅い方が非推奨にならないのはなぜですか?

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

4

5 に答える 5

42

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

警告

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

ページを少し下に進むと、次のように表示されます。

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

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

于 2009-09-01T10:00:54.837 に答える
19

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

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

于 2009-09-01T10:00:20.253 に答える
5

どちらがより高速で優れているかについては、多くの議論があります。

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

一般的なコンセンサスは、PCRE が全体的な解決策として優れているということですが、特定のページに大量のトラフィックがあり、PHP6 を必要としない場合は、テストする価値があるかもしれません。たとえば、PHP マニュアルのコメントから:

PHP で Perl 検索用に POSIX 正規表現を廃止することは、既製の部屋と壁のある家を木の板とレンガで置き換えるようなものです。もちろん、いくつかのパーツを組み合わせて使用​​することもできますが、すべてのパーツを目の前に並べて変更する方がはるかに簡単です。

PCRE は POSIX RE よりも高速ですか? 常にではない。ここ Cynergi での最近の検索エンジン プロジェクトでは、データを処理するのに 3 分かかったいくつかのかわいい ereg_replace() 関数を含む単純なループがありました。その 10 行のループを 100 行の手書きコードに変更して置き換えたところ、ループは同じデータを処理するのに 10 秒かかりました! これにより、場合によっては何ができるかがわかりました非常に遅い正規表現である必要があります。最近、Perl 互換の正規表現 (PCRE) を調べることにしました。ほとんどのページで、PCRE は POSIX よりも高速であると主張されていますが、そうではないという主張もいくつかあります。私は自分のベンチマークを決めました。私の最初のいくつかのテストでは、PCRE の方が高速であることが確認されましたが、結果は他の結果とはわずかに異なっていたので、ここで 8000 行の安全な (そして高速な) Web メール プロジェクトで RE を使用したすべてのケースをベンチマークすることにしました。それをチェックするCynergi。結果?決定的ではありません!ときにPCRE より高速 (場合によっては 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}) は、PCRE に変換した場合よりも POSIX の方が 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}/ は、POSIX RE よりも PCRE の方が 2.5 倍高速です。ereg_replace( "[^a-zA-Z0-9-]+", "", $m ); のような単純な置換パターン POSIX RE では、PCRE よりも 2 倍高速です。by[ \t]+([^ \t]+)[ \t]/i は POSIX RE バージョンよりも 30 倍高速です! 大文字と小文字の区別に関しては、これまでのところ PCRE が最良の選択肢のようです。しかし、ereg/eregi の非常に奇妙な動作を見つけました。非常に単純な POSIX RE (^|\r|\n)mime-version[ \t]: eregi() は 3.60 秒 (テスト ベンチマークの数値にすぎません) かかることがわかりましたが、対応する PCRE は 0.16 秒かかりました! しかし、ereg() (大文字と小文字を区別) を使用すると、POSIX RE 時間は 0.08 秒に短縮されました! そこでさらに調べてみました。POSIX RE 自体で大文字と小文字を区別しないようにしました。私はこれまでに得ました: (^|\r|\n)[mM][iI][mM][eE]-vers[iI][oO][nN][ \t]*: このバージョンも 0.08 かかりました秒。しかし、変更されていない「v」、「e」、「r」、または「s」のいずれかの文字に同じルールを適用しようとすると、時間は 3.60 秒のマークに戻り、徐々にではなく、すぐに戻ります。それで!テストデータには、「vers」、他の「mime」単語、またはPOSIXパーサーを混乱させる可能性のある「ion」が含まれていなかったため、途方に暮れています。結論: PCRE / POSIX RE を常にベンチマークして、最速を見つけてください。テストは、コマンド ラインから Windows で PHP 5.1.2 を使用して実行されました。ペドロ フレイレ cynergi.com

于 2009-09-01T10:30:12.393 に答える
4

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

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

于 2011-06-24T17:51:35.097 に答える
3

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

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

于 2009-09-01T10:01:20.827 に答える