PHP ereg против preg


Я заметил, что в библиотеке регулярных выражений PHP есть выбор между ereg и preg. В чем разница? Является ли один быстрее другого, и если да, то почему более медленный не является устаревшим?

Существуют ли какие-либо ситуации, в которых лучше использовать одно вместо другого?

Author: hakre, 2009-09-01

5 answers

Посещение php.net/ereg отображает следующее:

Предупреждение

Эта функция УСТАРЕЛА с PHP 5.3.0 и УДАЛЕНА с PHP 6.0.0. Полагаться на эту функцию крайне не рекомендуется.

Чуть ниже по странице, и мы читаем следующее:

Примечание: preg_match(), который использует синтаксис регулярных выражений, совместимый с Perl, часто является более быстрой альтернативой ereg().

Обратите внимание на мой акцент.

 41
Author: Sampson, 2009-09-01 10:00:54

Preg - это библиотека регулярных выражений, совместимая с Perl
ereg - это библиотека регулярных выражений, соответствующая POSIX

У них немного другой синтаксис, и preg в некоторых случаях немного быстрее. ereg устарел (и он удален в php6), поэтому я бы не рекомендовал его использовать.

 16
Author: Yacoby, 2009-09-01 10:17:22

Существует много дискуссий о том, что быстрее и лучше.

Если вы планируете когда-нибудь перейти на PHP6, ваше решение принято. В противном случае:

Общее мнение заключается в том, что PCRE является лучшим решением для всех, но если у вас есть определенная страница с большим количеством трафика, и вам не нужен PHP6, возможно, стоит провести некоторое тестирование. Например, из комментариев руководства по PHP:

Устаревшее регулярное выражение POSIX в PHP для поиска на Perl похоже на замену деревянного доски и кирпич для дома с быстровозводимыми комнатами и стенами. Конечно, вы можете смешивать и сочетать некоторые части, но это намного проще изменить со всеми частями разложенный перед тобой.

PCRE быстрее, чем POSIX RE? Не всегда. В недавнем проекте поисковой системы здесь , в Cynergi, у меня был простой цикл с несколькими симпатичными функциями ereg_replace() , для обработки данных потребовалось 3 минуты. Я изменил этот 10-строчный цикл на 100-строчный рукописный код для замены и теперь циклу потребовалось 10 секунд, чтобы обработать те же данные! Это открыло мне глаза на то, что может В НЕКОТОРЫХ СЛУЧАЯХ быть очень медленными регулярными выражениями. В последнее время я решил изучить Perl-совместимый обычный выражения (PCRE). Большинство страниц утверждают, PCRE быстрее, чем POSIX, но некоторые утверждают обратное. Я выбрал свои собственные марки. Мои первые несколько тестов подтвердили, что PCRE работает быстрее, но... результаты были немного иными, чем у других, поэтому я решил сравнить каждый случай ПОВТОРНОГО использования, который у меня был на 8000-линейной защищенной (и быстрый) проект веб-почты здесь по адресу Синерги, чтобы проверить это. Каковы результаты? Неубедительно! Иногда PCRE являются быстрее (иногда в 100 раз быстрее!), Но в некоторых других случаях POSIX RE быстрее (в 2 раза). Мне все еще нужно найти правило , когда одно или другое быстрее. Дело не только в размере данных поиска, количестве сопоставленных данных или "времени повторной компиляции", которое будет отображаться при повторении функция часто: один из них всегда будет быстрее другого. Но я не нашел здесь закономерности. Но, по правде говоря, я также не нашел времени, чтобы изучить исходный код и проанализировать проблему. Однако я могу привести вам несколько примеров. В POSIX RE ([0-9]{4})/([0-9]{2})/([0-9]{2})[^0-9]+ ([0-9]{2}):([0-9]{2}):([0-9]{2}) является На 30% быстрее в POSIX, чем при преобразовании в PCRE (даже если вы используете \d и \D и не жадное сопоставление). С другой стороны, аналогично ПКРЭ сложный шаблон /[0-9]{1,2}[ \t]+[a-za-Z]{3}[\t]+[0-9]{4}[ \т]+[0-9]{1,2}:[0-9]{1,2}(:[0-9]{1,2})?[ \т]+[+-][0-9]{4}/ в 2,5 раза быстрее в PCRE, чем в POSIX RE. Простые шаблоны замены, такие как ereg_replace("[^a-za-Z0-9-]+", "", $ m ); в POSIX RE в 2 раза быстрее, чем ПКР. И тогда мы снова запутаемся , потому что шаблон POSIX RE, такой как (^|\n|\r)начало-base64[\t]+[0-7]{3,4}[ \t]+......в 2 раза быстрее, чем POSIX RE, но PCRE без учета регистра /^Получено[\t]*:[ \t] по [\t]+([^ \t]+)[\t]/i в 30 раз быстрее, чем его ПОВТОРНАЯ версия POSIX! Когда дело доходит до чувствительности к регистру, PCRE до сих пор казался лучшим вариантом. Но я обнаружил действительно странное поведение эрега/эреги. На очень простом POSIX RE (^|\r|\n)mime-версия [\t]: Я обнаружил, что eregi() занимает 3,60 с (просто число в тестовом тесте), в то время как соответствующий PCRE занял 0,16 с! Но если Я использовал ereg() (с учетом регистра) , время восстановления POSIX сократилось до 0,08 с! Так что я дальнейшее расследование. Я пытался сделать сам POSIX не чувствителен к регистру. Я дошел до этого: (^|\r|\n)[мм][II][мм][EE]-версии [II][ОО][NN][ \t]*: Эта версия также заняла 0,08 с. Но если я попытаюсь применить то же правило к любой из букв "v", "e", "r" или "s", которые не изменены, время вернется к отметке 3,60 с, и не постепенно, а немедленно! В тестовых данных не было никаких " версий", других слов "mime" или каких-либо "ионов", которые могли бы сбить с толку POSIX синтаксический анализатор, так что я в растерянности. Итог: всегда проверяйте свой PCRE / POSIX RE, чтобы найти самый быстрый! Тесты были выполнены с PHP 5.1.2 под Windows, из командной строки. Педро Фрейре cynergi.com

 4
Author: SamGoody, 2009-09-01 10:30:12

Несмотря на то, что ereg устарел в PHP 5.3, функции mb_ereg* не являются устаревшими. Я считаю, что основная причина этого заключается в том, что PHP6 восстанавливает всю поддержку MB/Unicode, и поэтому старые "обычные" методы ereg бесполезны, так как mb_ereg будет новее/лучше.

Я знаю, что это не отвечает на вопрос о скорости, но это позволяет вам продолжать использовать как POSIX, так и PCRE.

 3
Author: Percy, 2011-06-24 17:51:35

Что ж, ereg и его производные функции (ereg_match и т. Д.) устарели в php5 и удаляются в php6, поэтому вам, вероятно, лучше всего использовать семейство preg.

Preg предназначен для регулярных выражений в стиле Perl, в то время как ereg является стандартным регулярным выражением POSIX.

 2
Author: Amber, 2009-09-01 10:01:20