Come posso convertire le espressioni ereg in preg in PHP?


140

Poiché le espressioni regolari POSIX (ereg) sono deprecate rispetto a PHP 5.3.0, mi piacerebbe conoscere un modo semplice per convertire le vecchie espressioni in PCRE (espressioni regolari compatibili Perl) (preg) .

Ad esempio, ho questa espressione regolare:

eregi('^hello world');

Come posso tradurre le espressioni in preg_matchespressioni compatibili?

Nota: questo post funge da segnaposto per tutti i post relativi alla conversione da ereg a preg e come opzioni duplicate per le domande correlate. Si prega di non chiudere questa domanda.

Relazionato:


2
@ yes123: Sì, questo è il punto, anche io sono stanco. Voglio un post wiki che spieghi effettivamente qualcosa in modo da poter chiudere tutte queste singole domande.
— netcoder

Penso che non sia necessario perché devi solo avvolgere il vecchio con un delimitatore. Inoltre penso che avresti potuto usare una domanda con risposta precedente per questo.
— dinamico

Ah, votato per una chiusura prima di leggere i commenti. Come segnaposto potrebbe servire a uno scopo, ma non c'è un'altra domanda più vecchia che avrebbe potuto servire come tale?
— Wrikken,

Hmm, davvero. ereg [php]non produce risultati molto utili. OK, posso prestare il mio supporto a questo.
— Wrikken,

8
Gente, sembra che abbiamo quasi creato un cerchio di domande chiuse su questo argomento, tutte rivolte l'una verso l'altra. Di questo passo saranno tutti chiusi :)
— Kev

Risposte:


142

Il più grande cambiamento nella sintassi è l'aggiunta di delimitatori .

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

I delimitatori possono essere praticamente qualsiasi cosa che non sia un carattere alfanumerico, una barra rovesciata o uno spazio bianco. I più utilizzati sono in genere ~, /e #.

Puoi anche usare le parentesi corrispondenti:

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

Se il delimitatore si trova nell'espressione regolare, devi scappare:

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

Puoi facilmente sfuggire a tutti i delimitatori e caratteri riservati in una stringa usando preg_quote :

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

Inoltre, PCRE supporta modificatori per varie cose. Uno dei più utilizzati è il modificatore senza distinzione tra maiuscole e minuscole i, l'alternativa a eregi :

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

È possibile trovare il riferimento completo alla sintassi PCRE in PHP nel manuale , nonché un elenco di differenze tra regex POSIX e PCRE per aiutare a convertire l'espressione.

Tuttavia, nel tuo semplice esempio non useresti un'espressione regolare:

stripos($str, 'hello world') === 0

2
Spiegazione meravigliosa! Vorrei solo aggiungere un caso speciale in cui stai convertendo da ereg a preg_match e devi sfuggire solo ai delimitatori e ai caratteri non riservati (poiché già funzionavano come caratteri speciali, non vogliamo sfuggirli) : preg_match ('/'. str_replace ('/', '\ /', $ expr). '/', $ str);
— Lolito,

Vale la pena notare in particolare che se si utilizzano parentesi corrispondenti, non è necessario sfuggire a nessun carattere "solo perché è lo stesso del delimitatore" come si fa con altri simboli come /^\/hello/nell'esempio. (a(b)c)è un PCRE perfettamente valido e delimitato. Personalmente mi piace usare le parentesi ()per ricordare a me stesso che la prima partita catturata è l'intera cosa.
— Niet the Dark Absol,

Posso dire che odio il PHP! (.. Solo che niente altro) devo cercare queste risposte fuori quando il mio server di hosting web condiviso viene aggiornato a una nuova versione e le error_logs ottenere pieno con questi avvertimenti: PHP Deprecated: Function ereg() is deprecated in.... Argh!
— c00000fd,

come convertire questo? $ regex = $ e. '((\. [^ \.'. $ e. '] [^'. $ e. '] *) | (\. \. [^'. $ e. '] +) | ([^ \. ] [^ '. $ e.'] *)) '. $ e. '\. \.' . $ E; per preg_math funziona semplicemente aggiungendo / modificatore /
— bdalina

32

La sostituzione di Ereg con preg (a partire da PHP 5.3.0) è stata la mossa giusta a nostro favore.

preg_match, che utilizza una sintassi di espressione regolare compatibile con Perl, è spesso un'alternativa più rapida a ereg.

Dovresti sapere 4 cose principali per portare gli schemi a preg:

  1. Aggiungi delimitatori (/):'pattern' => '/pattern/'

  2. Esci dal delimitatore se fa parte del modello: 'patt/ern' => '/patt\/ern/'
    raggiungilo a livello di codice nel modo seguente:
    $old_pattern = '<div>.+</div>';
    $new_pattern = '/' . addcslashes($old_pattern, '/') . '/';

  3. eregi (corrispondenza senza distinzione tra maiuscole e minuscole): 'pattern' => '/pattern/i' quindi, se si utilizza la funzione eregi per la corrispondenza senza distinzione tra maiuscole e minuscole, è sufficiente aggiungere 'i' alla fine del nuovo modello ('/ pattern /').

  4. Valori ASCII : In ereg, se si utilizza il numero nel modello, si presume che ci si riferisca all'ASCII di un carattere. Ma in preg, il numero non è trattato come valore ASCII. Quindi, se il tuo pattern contiene un valore ASCII nell'espressione ereg (ad esempio: nuova riga, tab ecc.) Allora convertilo in esadecimale e prefissalo con \ x.
    Example: 9(tab) becomes \x9 or alternatively use \t.


8

Dalla versione 5.3 di PHP, eregè obsoleto.

Passare da erega preg_matchè solo un piccolo cambiamento nel nostro modello.

Innanzitutto, devi aggiungere delimitatori al tuo codice, ad esempio:

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

per

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

Per eregiuna corrispondenza senza distinzione tra maiuscole e minuscole, inserire il'ultimo delimitatore, ad esempio:

eregi('pattern', 'string');

per

preg_match ('/pattern/i', 'string');

7

Esistono più differenze tra ereg()e preg_replace()non solo la sintassi:

  • Valore di ritorno:

    • In caso di errore : entrambi restituisconoFALSE
    • In nessuna corrispondenza : ereg()ritorna FALSE, preg_match()ritorna0
    • Alla corrispondenza : ereg()restituisce la lunghezza della stringa oppure 1, preg_match()restituisce sempre1
  • Matrice risultante di sottostringhe corrispondenti: se non viene rilevata alcuna sottostringa ( (b)in ...a(b)?), ereg()verrà visualizzato l' elemento corrispondente nel risultato FALSE, mentre in preg_match()essa non verrà impostato affatto.

Se uno non è abbastanza coraggioso per convertire la sua ereg()a preg_match(), lui o lei può usare mb_ereg () , che è ancora disponibile in PHP 7.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.