PHP ereg против preg

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

Есть ли ситуации, когда лучше использовать один над другим?


person Evernoob    schedule 01.09.2009    source источник


Ответы (5)


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

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

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

Еще немного вниз по странице и мы читаем это:

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

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

person Sampson    schedule 01.09.2009
comment
Как указал Перси, _1_ и другие многобайтовые функции ereg не устарели. - person Evernoob; 01.09.2009
comment
PCRE быстрее, чем POSIX RE? Не всегда. В недавнем проекте поисковой системы здесь, в Cynergi, у меня был простой цикл с несколькими симпатичными функциями ereg_replace(), которые обрабатывали данные за 3 минуты. Я заменил этот 10-строчный цикл на 100-строчный рукописный код для замены, и теперь циклу требовалось 10 секунд для обработки тех же данных! Это открыло мне глаза на то, что В НЕКОТОРЫХ СЛУЧАЯХ регулярные выражения могут быть очень медленными. Недавно я решил изучить Perl-совместимые регулярные выражения (PCRE). Большинство страниц утверждают, что PCRE быстрее, чем POSIX, но некоторые утверждают обратное. Я выбрал собственные ориентиры. Мои первые несколько тестов подтвердили, что PCRE работает быстрее, но... результаты немного отличались от других, поэтому я решил сравнить каждый случай использования RE, который у меня был, в безопасном (и быстром) проекте веб-почты с 8000 строками здесь, на 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}) на 30% быстрее в POSIX, чем при преобразовании в PCRE (даже если вы используете \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 в 2,5 раза быстрее, чем в POSIX RE. Простые шаблоны замены, такие как ereg_replace("[^a-zA-Z0-9-]+", "", $m); в 2 раза быстрее в POSIX RE, чем в PCRE. А затем мы снова запутались, потому что шаблон POSIX RE, такой как (^|\n|\r)begin-base64[ \t]+[0-7]{3,4}[ \t]+...... в 2 раза быстрее, чем POSIX RE, но PCRE без учета регистра /^Received[ \t]*:[ \t]by[ \t]+([^ \t]+)[ \t]/i В 30 раз быстрее, чем его версия POSIX RE! Когда дело доходит до чувствительности к регистру, 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 с. Но если я попытаюсь применить то же правило к любой из букв «в», «е», «р» или «с», которые не изменились, время вернется к отметке 3,60 с, и не постепенно, а сразу. так! В тестовых данных не было никаких «версий», других «мимических» слов или любого «иона», который мог бы сбить с толку парсер POSIX, поэтому я в растерянности. Итог: всегда сравнивайте свои PCRE / POSIX RE, чтобы найти самый быстрый! Тесты проводились с PHP 5.1.2 под Windows, из командной строки. Педро Фрейре cynergi.com - person Benjamin Atkin; 10.07.2012

preg – это Perl-совместимая библиотека регулярных выражений
ereg – совместимая с POSIX библиотека регулярных выражений.

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

person Yacoby    schedule 01.09.2009

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

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

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

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

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

person SamGoody    schedule 01.09.2009

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

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

person Percy    schedule 24.06.2011

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

а, ок, спасибо, я не видел этого по какой-то причине. До свидания эрег я полагаю! Принятый ответ.

person Amber    schedule 01.09.2009