Как преобразовать выражения 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.