Comment puis-je convertir des expressions ereg en preg en PHP?

140

Puisque les expressions régulières POSIX (ereg) sont obsolètes depuis PHP 5.3.0, j'aimerais connaître un moyen simple de convertir les anciennes expressions en PCRE (Perl Compatible Regular Expressions) (preg) .

Par exemple, j'ai cette expression régulière:

eregi('^hello world');

Comment puis-je traduire des expressions en preg_matchexpressions compatibles?

Remarque: cet article sert d'espace réservé pour tous les articles liés à la conversion d'ereg en preg, et d'options de duplication pour les questions connexes. Veuillez ne pas fermer cette question.

En relation:

netcoder
la source
2
@ yes123: Oui, c'est le but, j'en ai marre aussi. Je veux un article wiki qui explique réellement quelque chose afin que nous puissions fermer toutes ces questions individuelles.
netcoder
Je ne pense pas que cela soit nécessaire car il vous suffit d'envelopper l'ancien avec un délimiteur. Aussi, je pense que vous auriez pu utiliser une question à réponse précédente pour cela.
dynamique
Ah, j'ai voté pour une clôture avant de lire les commentaires. En tant qu'espace réservé, cela pourrait servir un objectif, mais n'y a-t-il pas une autre question plus ancienne qui aurait pu servir de tel?
Wrikken
Hmm, en effet. ereg [php]ne donne pas beaucoup de résultats utiles. OK, je peux apporter mon soutien à celui-ci.
Wrikken
8
Mes amis, il semble que nous ayons presque créé un cercle de questions fermées sur ce sujet qui se pointent toutes les unes vers les autres. À ce rythme, ils seront tous fermés :)
Kev

Réponses:

142

Le plus gros changement dans la syntaxe est l'ajout de délimiteurs .

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

Les délimiteurs peuvent être à peu près tout ce qui n'est pas alphanumérique, une barre oblique inverse ou un espace blanc. Les plus utilisés sont généralement ~, /et #.

Vous pouvez également utiliser des crochets correspondants:

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

Si votre délimiteur se trouve dans l'expression régulière, vous devez l'échapper:

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

Vous pouvez facilement échapper à tous les délimiteurs et caractères réservés dans une chaîne en utilisant preg_quote :

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

En outre, PCRE prend en charge les modificateurs pour diverses choses. L'un des plus utilisés est le modificateur insensible à la casse i, l'alternative à eregi :

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

Vous pouvez trouver la référence complète à la syntaxe PCRE en PHP dans le manuel , ainsi qu'une liste des différences entre POSIX regex et PCRE pour faciliter la conversion de l'expression.

Cependant, dans votre exemple simple, vous n'utiliserez pas d'expression régulière:

stripos($str, 'hello world') === 0
netcoder
la source
2
Merveilleuse explication! Je voudrais juste ajouter un cas particulier dans lequel vous convertissez d' ereg en preg_match et vous devez échapper uniquement aux délimiteurs et non aux caractères réservés (car ils fonctionnaient déjà comme des caractères spéciaux, nous ne voulons pas les échapper) : preg_match ('/'. str_replace ('/', '\ /', $ expr). '/', $ str);
Lolito
Il est particulièrement intéressant de noter que si vous utilisez des crochets correspondants, vous n'avez pas besoin d'échapper aux caractères "simplement parce que c'est le même que le délimiteur" comme vous le faites avec d'autres symboles comme l' /^\/hello/exemple. (a(b)c)est un PCRE parfaitement valide et délimité. Personnellement, j'aime utiliser des parenthèses ()pour me rappeler que le premier match capturé est tout.
Niet the Dark Absol
Puis-je dire, je déteste freaking PHP! (.. Juste que rien d' autre) , je dois chercher ces réponses quand mon serveur d' hébergement Web partagé est mis à jour vers une nouvelle version et les error_logs OBTENEZ avec ces avertissements: PHP Deprecated: Function ereg() is deprecated in.... Argh!
c00000fd
comment convertir cela? $ regex = $ e. '((\. [^ \.'. $ e. '] [^'. $ e. '] *) | (\. \. [^'. $ e. '] +) | ([^ \. ] [^ '. $ e.'] *)) '. $ e. «\. \.» . $ e; à preg_math, cela fonctionne en ajoutant simplement / modifier /
bdalina
32

Le remplacement de Ereg par preg (à partir de PHP 5.3.0) était une bonne décision en notre faveur.

preg_match, qui utilise une syntaxe d'expression régulière compatible Perl, est souvent une alternative plus rapide à ereg.

Vous devez savoir 4 choses principales pour porter les modèles ereg vers preg:

  1. Ajouter des délimiteurs (/):'pattern' => '/pattern/'

  2. Délimiteur d'échappement s'il fait partie du modèle: 'patt/ern' => '/patt\/ern/'
    réalisez-le par programme de la manière suivante:
    $old_pattern = '<div>.+</div>';
    $new_pattern = '/' . addcslashes($old_pattern, '/') . '/';

  3. eregi (correspondance insensible à la casse): 'pattern' => '/pattern/i' Donc, si vous utilisez la fonction eregi pour la correspondance insensible à la casse, ajoutez simplement 'i' à la fin du nouveau motif ('/ pattern /').

  4. Valeurs ASCII : Dans ereg, si vous utilisez un nombre dans le modèle, il est supposé que vous faites référence à l'ASCII d'un caractère. Mais dans preg, le nombre n'est pas traité comme une valeur ASCII. Donc, si votre modèle contient une valeur ASCII dans l'expression ereg (par exemple: nouvelle ligne, tabulations, etc.), convertissez-le en hexadécimal et préfixez-le avec \ x.
    Example: 9(tab) becomes \x9 or alternatively use \t.

Sumoanand
la source
8

À partir de la version 5.3 de PHP, eregest obsolète.

Passer de eregà preg_matchn'est qu'un petit changement dans notre modèle.

Tout d'abord, vous devez ajouter des délimiteurs à votre code, par exemple:

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

à

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

Pour une eregicorrespondance insensible à la casse, mettez iaprès le dernier délimiteur, par exemple:

eregi('pattern', 'string');

à

preg_match ('/pattern/i', 'string');
Narayan
la source
7

Il y a plus de différences entre ereg()et preg_replace()que juste la syntaxe:

  • Valeur de retour:

    • En cas d'erreur : les deux retournentFALSE
    • Pas de match : ereg()retourne FALSE, preg_match()retourne0
    • En match :ereg() retourne la longueur de chaîne ou 1, preg_match()retourne toujours1
  • Tableau résultant de sous-chaînes correspondantes: Si une sous-chaîne n'est pas du tout trouvée ( (b)dans...a(b)? ), l'élément correspondant dans ereg()result sera FALSE, alors preg_match()qu'il ne sera pas du tout défini.

Si quelqu'un n'est pas assez courageux pour le convertir ereg()en preg_match(), il ou elle peut utiliser mb_ereg () , qui est toujours disponible en PHP 7.

Roman Hocke
la source