Как я могу преобразовать выражения ereg в preg в PHP?
Поскольку регулярные выражения POSIX (ereg) устарели начиная с PHP 5.3.0, я хотел бы знать простой способ преобразования старых выражений в PCRE (регулярные выражения, совместимые с Perl) (preg).
Например, у меня есть это регулярное выражение:
eregi('^hello world');
Как я могу перевести выражения в preg_match
совместимые выражения?
Примечание. Этот пост служит заполнителем для всех постов, связанных с переходом с ereg на preg, и дублирует варианты связанных вопросов. Пожалуйста, не закрывайте этот вопрос.
Связанные с:
4 ответа
Самое большое изменение в синтаксисе - это добавление разделителей.
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 поддерживает модификаторы для разных вещей. Одним из наиболее используемых является регистрозависимый модификатор i
Альтернатива eregi:
eregi('^hello', 'HELLO');
preg_match('/^hello/i', 'HELLO');
Вы можете найти полную ссылку на синтаксис PCRE в PHP в руководстве, а также список различий между POSIX regex и PCRE, чтобы помочь преобразовать выражение.
Однако в вашем простом примере вы бы не использовали регулярное выражение:
stripos($str, 'hello world') === 0
Замена 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 для сопоставления без учета регистра, просто добавьте "i" в конце нового шаблона ("/pattern/").Значения ASCII: если вы используете число в шаблоне, предполагается, что вы ссылаетесь на ASCII символа. Но в preg число не рассматривается как значение ASCII. Итак, если ваш шаблон содержит значение ASCII в выражении ereg (например: новая строка, табуляция и т. Д.), Преобразуйте его в шестнадцатеричное и добавьте префикс \x.
Example: 9(tab) becomes \x9 or alternatively use \t.
Начиная с версии 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');
Есть больше различий между ereg()
а также preg_replace()
чем просто синтаксис:
Возвращаемое значение:
- При ошибке: оба возвращаются
FALSE
- Ни на один матч:
ereg()
возвращаетсяFALSE
,preg_match()
возвращается0
- На матче:
ereg()
возвращает длину строки или1
,preg_match()
всегда возвращается1
- При ошибке: оба возвращаются
Результирующий массив совпадающих подстрок: если какая-либо подстрока вообще не найдена (
(b)
в...a(b)?
), соответствующий пункт вereg()
результат будетFALSE
, пока вpreg_match()
это не будет установлено вообще.
Если человек не достаточно смел, чтобы обратить его или ее ereg()
в preg_match()
он или она может использовать mb_ereg (), которая все еще доступна в PHP 7.