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.