Як можна перетворити вирази ereg в preg в PHP?


140

Оскільки POSIX регулярні вирази (ereg) застаріли з PHP 5.3.0, я хотів би знати простий спосіб перетворення старих виразів у PCRE (Perl Compatible Regular Express) (preg) .

Наприклад, у мене є такий регулярний вираз:

eregi('^hello world');

Як я можу перевести вирази в preg_matchсумісні вирази?

Примітка. Ця публікація слугує заповнювачем усіх публікацій, пов’язаних із перетворенням з ereg в preg, і як дублікати варіантів пов'язаних питань. Будь ласка, не закривайте це питання.

Пов'язані:


2
@ yes123: Так, справа в цьому, і мені це теж набридло. Я хочу, щоб публікація у вікі фактично щось пояснювала, щоб ми могли закрити всі ці окремі запитання.
netcoder

Я думаю, в цьому немає необхідності, тому що потрібно просто обернути старе роздільником. Також я думаю, що ви могли використати для цього попередній відповідь.
динамічний

Ах, проголосував за закриття, перш ніж читати коментарі. Як заповнювач це міг би служити цілі, але хіба не існує ще одного старого питання, яке могло б послужити таким?
Wrikken

Хм, справді. ereg [php]не дає дуже багато корисних результатів. Гаразд, я можу надати підтримку цьому.
Wrikken

8
Люди, ми, здається, майже створили коло закритих питань на цю тему, всі вказуючи один на одного. З цією швидкістю їх усіх закриють :)
Кев

Відповіді:


142

Найбільша зміна синтаксису - додавання роздільників .

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

2
Чудове пояснення! Я хотів би просто додати спеціальний випадок, коли ви перетворюєтесь з ereg в preg_match, і вам потрібно уникати лише роздільників, а не зарезервованих символів (оскільки вони вже працювали як спеціальні символи, ми не хочемо їх уникати) : preg_match ('/'. str_replace ('/', '\ /', $ expr). '/', $ str);
Лоліто

Особливо варто зауважити, що якщо ви використовуєте відповідні дужки, вам не потрібно уникати жодних символів "лише тому, що це те саме, що і роздільник", як ви робите з іншими символами на зразок /^\/hello/прикладу. (a(b)c)є абсолютно дійсним, обмеженим PCRE. Я особисто люблю використовувати дужки, ()щоб нагадати собі, що перший захоплений збіг - це вся справа.
Niet the Dark Absol

Чи можу я сказати, я ненавиджу ненавиджу PHP! (.. Тільки що нічого іншого) я повинен шукати відповіді на ці питання, коли мій віртуальний хостинг сервер інтернету оновлюється до нової версії і error_logдобуде сповнений ці попередження: PHP Deprecated: Function ereg() is deprecated in.... Арг!
c00000fd

як це перетворити? $ regex = $ e. '((\. [^ \.'. $ e. '] [^'. $ e. '] *) | (\. \. [^'. $ e. '] +) | ([^ \. ] [^ '. $ e.'] *)) '. $ е. '\. \.' . $ e; to preg_math це виконувати роботу, просто додавши / модифікатор /
bdalina

32

Заміна Ereg на preg (станом на PHP 5.3.0) була правильним кроком на нашу користь.

preg_match, який використовує сумісний з Perl синтаксис регулярного вираження, часто є швидшою альтернативою ereg.

Вам слід знати 4 основні речі, щоб передати шаблони ereg до прег:

  1. Додати роздільники (/):'pattern' => '/pattern/'

  2. Розмежувач біг, якщо він є частиною шаблону: 'patt/ern' => '/patt\/ern/'
    Досягніть його програмно наступним чином:
    $old_pattern = '<div>.+</div>';
    $new_pattern = '/' . addcslashes($old_pattern, '/') . '/';

  3. eregi (відповідність регістру невідповідності): 'pattern' => '/pattern/i' Отже, якщо ви використовуєте функцію eregi для невідповідності випадків, просто додайте "i" в кінці нового шаблону ('/ pattern /').

  4. Значення ASCII : якщо ви використовуєте номер у шаблоні ereg, передбачається, що ви посилаєтесь на ASCII символу. Але в preg число не трактується як значення ASCII. Отже, якщо ваш візерунок містить значення ASCII у виразі ereg (наприклад: новий рядок, вкладки тощо), тоді перетворите його в шістнадцятковий і приставте його до \ x.
    Example: 9(tab) becomes \x9 or alternatively use \t.


8

З 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');

7

Існує більше відмінностей між 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.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.