Як можна перетворити вирази 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.