Как преобразовать выражения ereg в preg в PHP?

Поскольку регулярные выражения POSIX (ereg) устарели с PHP 5.3.0, я хотел бы знать простой способ преобразования старого выражения для PCRE (регулярные выражения, совместимые с Perl) (preg).

В качестве примера у меня есть это регулярное выражение:

eregi('^hello world');

Как преобразовать выражения в preg_match совместимые выражения?

Примечание. Этот пост служит заполнителем всех сообщений, связанных с преобразованием из ereg в preg, и в качестве дублирующих параметров для связанных вопросов. Пожалуйста, не закрывайте этот вопрос.

Связанный:

Ответ 1

Самым большим изменением в синтаксисе является добавление delimiters.

ereg('^hello', $str);
preg_match('/^hello/', $str);

Разделители могут быть практически любыми, что не является буквенно-цифровым, обратным слэшем или символом пробела. Наиболее часто используются ~, / и #.

Вы также можете использовать соответствующие скобки:

preg_match('[^hello]', $str);
preg_match('(^hello)', $str);
preg_match('{^hello}', $str);
// etc

Если ваш разделитель найден в регулярном выражении, вам нужно его избежать:

ereg('^/hello', $str);
preg_match('/^\/hello/', $str);

Вы можете легко избежать всех разделителей и зарезервированных символов в строке с помощью preg_quote:

$expr = preg_quote('/hello', '/');
preg_match('/^'.$expr.'/', $str);

Кроме того, PCRE поддерживает modifiers для разных вещей. Одним из наиболее используемых является модификатор без учета регистра i, альтернативный eregi:

eregi('^hello', 'HELLO');
preg_match('/^hello/i', 'HELLO');

Вы можете найти полную ссылку на синтаксис PCRE в PHP в руководстве, а также список различий между POSIX regex и PCRE, чтобы помочь преобразовать выражение.

Однако в вашем простом примере вы не будете использовать регулярное выражение:

stripos($str, 'hello world') === 0

Ответ 2

Замена Ereg с помощью preg (начиная с PHP 5.3.0) была правильным шагом в нашу пользу.

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

Вы должны знать 4 основных элемента для переноса шаблонов ereg в preg:

  • Добавить разделители (/): 'pattern' => '/pattern/'

  • разделитель Escape, если он является частью шаблона: 'patt/ern' => '/patt\/ern/'
    Достичь этого программно следующим образом:
    $old_pattern = '<div>.+</div>';
    $new_pattern = '/' . addcslashes($old_pattern, '/') . '/';

  • eregi (нечувствительность к регистру): 'pattern' => '/pattern/i' Итак, если вы используете функцию eregi для совпадения case insenstive, просто добавьте 'i' в конец нового шаблона ('/pattern/').

  • Значения ASCII. В ereg, если вы используете номер в шаблоне, предполагается, что вы ссылаетесь на ASCII символа. Но в preg число не рассматривается как значение ASCII. Таким образом, если ваш шаблон содержит значение ASCII в выражении ereg (например: новая строка, вкладки и т.д.), То преобразовать его в шестнадцатеричный и префикс с помощью \x.
    Example: 9(tab) becomes \x9 or alternatively use \t.

Ответ 3

Начиная с версии PHP 5.3, ereg устарел.

Переход от ereg к preg_match - это лишь небольшое изменение в нашем шаблоне.

Во-первых, вы должны добавить разделители в свой код, например:

ereg('A-Z0-9a-z', 'string');

в

preg_match('/A-Z0-9a-z/', 'string');

Для eregi нечувствительности к регистру, поместите i после последнего разделителя, например:

eregi('pattern', 'string');

в

preg_match ('/pattern/i', 'string');

Ответ 4

Есть больше различий между ereg() и preg_replace(), чем просто синтаксис:

  • Возвращаемое значение:

    • При ошибке: оба возвращают FALSE
    • Не соответствует: ereg() возвращает FALSE, preg_match() возвращает 0
    • В соответствии с: ereg() возвращает длину строки или 1, preg_match() всегда возвращает 1
  • Результирующий массив совпадающих подстрок: если какая-либо подстрока вообще не найдена ((b) in ...a(b)?), соответствующий элемент в ereg() будет FALSE, а в preg_match() он будет не устанавливаться вообще.

Если вы недостаточно храбр, чтобы преобразовать его ereg() в preg_match(), он может использовать mb_ereg(), который по-прежнему доступен в PHP 7.