Jak mogę przekonwertować wyrażenia ereg na preg w PHP?

140

Ponieważ wyrażenia regularne POSIX (ereg) są przestarzałe od PHP 5.3.0, chciałbym poznać łatwy sposób konwersji starych wyrażeń na PCRE (wyrażenia regularne kompatybilne z Perlem) (preg) .

Na przykład mam to wyrażenie regularne:

eregi('^hello world');

Jak mogę przetłumaczyć wyrażenia na preg_matchzgodne wyrażenia?

Uwaga: ten post służy jako miejsce zastępcze dla wszystkich postów związanych z konwersją z ereg na preg oraz jako duplikat opcji dla powiązanych pytań. Nie zamykaj tego pytania.

Związane z:

netcoder
źródło
2
@ yes123: Tak, o to chodzi, ja też jestem tym zmęczony. Chcę postu na wiki, który faktycznie coś wyjaśnia, abyśmy mogli zamknąć wszystkie te indywidualne pytania.
netcoder
Myślę, że nie ma takiej potrzeby, ponieważ wystarczy owinąć stary separatorem. Myślę też, że mógłbyś wykorzystać w tym celu poprzednie pytanie, na które udzielono odpowiedzi.
dynamiczny
Ach, zagłosowałem za zamknięciem przed przeczytaniem komentarzy. Jako symbol zastępczy może służyć jakiemuś celowi, ale czy nie ma innego starszego pytania, które mogłoby służyć jako takie?
Wrikken
Hmm, rzeczywiście. ereg [php]nie daje zbyt użytecznych wyników. OK, mogę udzielić mi wsparcia dla tego.
Wrikken
8
Ludzie, wydaje się, że prawie stworzyliśmy krąg zamkniętych pytań na ten temat, wszystkie skierowane na siebie. W tym tempie wszystkie będą zamknięte :)
Kev

Odpowiedzi:

142

Największą zmianą w składni jest dodanie ograniczników .

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

Separatorami może być prawie wszystko, co nie jest alfanumeryczne, odwrotnym ukośnikiem lub białym znakiem. Najbardziej powszechnie stosowane są ~, /i #.

Możesz również użyć pasujących nawiasów:

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

Jeśli separator znajduje się w wyrażeniu regularnym, musisz go zmienić:

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

Możesz łatwo zmienić znaczenie wszystkich separatorów i znaków zastrzeżonych w ciągu, używając preg_quote :

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

Ponadto PCRE obsługuje modyfikatory do różnych rzeczy. Jednym z najczęściej używanych jest modyfikator bez rozróżniania wielkości liter i, alternatywa dla eregi :

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

Pełne odniesienie do składni PCRE w PHP można znaleźć w podręczniku , a także listę różnic między wyrażeniami regularnymi POSIX i PCRE, aby pomóc w konwersji wyrażenia.

Jednak w prostym przykładzie nie użyłbyś wyrażenia regularnego:

stripos($str, 'hello world') === 0
netcoder
źródło
2
Cudowne wyjaśnienie! Chciałbym tylko dodać specjalny przypadek, w którym konwertujesz z ereg na preg_match i musisz uciec tylko ogranicznikami, a nie znakami zastrzeżonymi (ponieważ działały już jako znaki specjalne, nie chcemy ich uciec) : preg_match ('/'. str_replace ('/', '\ /', $ wyr). '/', $ str);
Lolito
Szczególnie warto zauważyć, że jeśli używasz pasujących nawiasów, nie musisz zmieniać żadnego znaku „tylko dlatego, że jest taki sam jak separator”, tak jak w przypadku innych symboli, takich jak /^\/hello/przykład. (a(b)c)jest doskonale poprawnym, ograniczonym PCRE. Osobiście lubię używać nawiasów, ()aby przypomnieć sobie, że pierwsze przechwycone dopasowanie to całość.
Niet the Dark Absol
Mogę powiedzieć, że nienawidzę PHP! (.. Wystarczy, że nic innego) mam szukać odpowiedzi na te pytania, kiedy my wspólne hosting serwer zostanie zaktualizowany do nowej wersji i error_logs uzyskać pełny z tych ostrzeżeń: PHP Deprecated: Function ereg() is deprecated in.... Argh!
c00000fd
jak to przekonwertować? $ regex = $ e. '((\. [^ \.'. $ e. '] [^'. $ e. '] *) | (\. \. [^'. $ e. '] +) | ([^ \. ] [^ '. $ e.'] *)) '. $ e. '\. \.' . $ e; to preg_math działa, po prostu dodając / modyfikator /
bdalina
32

Zastąpienie Ereg preg (od PHP 5.3.0) było dobrym posunięciem na naszą korzyść.

preg_match, który używa składni wyrażeń regularnych zgodnej z Perlem, jest często szybszą alternatywą dla ereg.

Powinieneś wiedzieć 4 główne rzeczy, aby przenieść wzorce ereg na preg:

  1. Dodaj ograniczniki (/):'pattern' => '/pattern/'

  2. Separator ucieczki, jeśli jest częścią wzorca: 'patt/ern' => '/patt\/ern/'
    Osiągnij go programowo w następujący sposób:
    $old_pattern = '<div>.+</div>';
    $new_pattern = '/' . addcslashes($old_pattern, '/') . '/';

  3. eregi (dopasowywanie bez uwzględniania wielkości liter): 'pattern' => '/pattern/i' Tak więc, jeśli używasz funkcji eregi do dopasowywania bez uwzględniania wielkości liter, po prostu dodaj „i” na końcu nowego wzorca („/ wzorzec /”).

  4. Wartości ASCII : W ereg, jeśli używasz liczby we wzorcu, zakłada się, że odnosisz się do ASCII znaku. Ale w preg liczba nie jest traktowana jako wartość ASCII. Tak więc, jeśli twój wzorzec zawiera wartość ASCII w wyrażeniu ereg (na przykład: nowa linia, tabulatory itp.), Przekonwertuj go na szesnastkowy i poprzedz go znakiem \ x.
    Example: 9(tab) becomes \x9 or alternatively use \t.

Sumoanand
źródło
8

Od wersji PHP 5.3 eregjest przestarzałe.

Przejście od eregdo preg_matchto tylko niewielka zmiana w naszym schemacie.

Najpierw musisz dodać ograniczniki do swojego kodu, np:

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

do

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

Aby eregidopasować bez rozróżniania wielkości liter, umieść ipo ostatnim ograniczniku, np .:

eregi('pattern', 'string');

do

preg_match ('/pattern/i', 'string');
Narayan
źródło
7

Istnieje więcej różnic między ereg()i preg_replace()niż tylko składnią:

  • Wartość zwracana:

    • W przypadku błędu : oba zwracają sięFALSE
    • W przypadku braku dopasowania : ereg()wraca FALSE, preg_match()wraca0
    • Po dopasowaniu : ereg()zwraca długość ciągu lub 1, preg_match()zwraca zawsze1
  • Wynikowa tablica dopasowanych podciągów: Jeśli jakiś podciąg nie zostanie w ogóle znaleziony ( (b)w ...a(b)?), odpowiadający ereg()wynik będzie taki FALSE, podczas gdy w preg_match()nim nie zostanie w ogóle ustawiony.

Jeśli ktoś nie jest na tyle odważny, aby przekonwertować swoją ereg()na preg_match()to, może użyć mb_ereg () , który jest nadal dostępny w PHP 7.

Roman Hocke
źródło