Général

Les PCRE

Les POSIX

Pratique

Linux

Spécial php

Les billets de fred

Les Plus des fonctions PCRE


Comme je l'ai dit dans la page sur les PCRE, les fonctions Perl Compatible offrent des fonctionnalités bien plus grandes que les POSIX. Un petit rappel :

    * Plus rapide
    * Utilisation des références arrières
    * Capture de toutes les occurrences
    * Rendre un quantificateur non gourmand
    * Utilisation des parenthèses non capturantes
    * Utilisation d'une foule d'options
    * Utilisation d'assertions, masques conditionnels
    * Fonctions de callback
    * Etc...

 La rapidité:

Dans cette partie réservée aux multiples fonctionnalités des PCRE, je vais vous apprendre pourquoi les PCRE sont de 4 à 5 fois plus rapide que les POSIX à motif identique bien entendu.
Exemple : On va chercher le mot PCRE dans la phrase du dessus.
<?php
preg_match('`PCRE`',$phrase,$out);
?>

Cette fonction preg_match retournera son résultat, soit la première occurrence de PCRE 4 à 5 fois plus vite que son équivalent POSIX.
<?php
ereg('PCRE',$phrase,$out);
?>

J'en entends déjà hurler au scandale en me disant que strpos(); aurait fait le travail de la même manière et encore plus vite.
Oui bien évidement, mais la démarche simpliste utilisée ici, ne nous sert que pour l'exemple.

 La gourmandise:

Par défaut, les quantificateurs que vous connaissez tous... euh... non vous ne savez plus ????
Bon, je suis bon prince, je vous les rappelle : ce sont les ?, +, *, {1,} et {0,}

Donc disais-je, ces quantificateurs sont TOUJOURS gourmands dans une POSIX, mais dans une PCRE, ils ne le sont que PAR DEFAUT

Pour illustrer cela, je vais vous donner un exemple de recherche sur une balise de lien, placée dans un texte. On va donc chercher à capturer la partie URL entre " dans ce genre de syntaxe :

<a href="http://www.monsite.com/mapage.php">Mon url à récupérer</a>

<?php
$chaine='Mon texte avec <a href="http://www.monsite.com/mapage.php">mon url que je veux</a> dans cette phrase';
?>

Illustrons la gourmandise avec une POSIX :
<?php
ereg('<a href=(.*)>', $chaine, $out);
?>
Le résultat de cette recherche donnera :
"http://www.monsite.com/mapage.php">mon url que je veux</a

Maintenant, avec la fonction (équivalente) PCRE
<?php
preg_match('`<a href=(.*?)>', $chaine, $out);
?>

Le résultat de cette recherche donnera exactement ce que l'on recherche, soit :
"http://www.monsite.com/mapage.php"
Explication :

Vous savez tous que le point . (dot) est le métacaractère qui permet de reconnaître n'importe quel caractère.
Dans la POSIX, ce métacaractère va tout reconnaître, y compris les > intermédiaires pour ne s'arrêter qu'à la hauteur du dernier > qu'il va rencontrer et terminer sa recherche.

Dans une PCRE par contre, on peut réduire cet effet de gourmandise grâce au ?
Il existe une autre manière de réduire la gourmandise en utilisant l'option U (ungreedy) mais on en parlera avec d'autres fonctions. Sachez déjà que l'option U agit sur la totalité du masque.
On aurait également pu utiliser une classe complémentée, mais le but est d'illustrer notre exemple pour une meilleure compréhension.

Capturer toutes les occurrences:

Les fonctions POSIX eregi(); ou la PCRE preg_match(); ne capture que la première occurrence rencontrée dans la chaîne. Si l'on veut matcher un texte entier et en retirer toutes les occurrences qui correspondent à notre motif, nous devrons employer preg_match_all();
-> voir la fonction ici : preg_match_all

Illustrons par un exemple :
<?php
$chaine='Contrairement aux POSIX, les PCRE permettent un emploi des assertions, des masques conditionnels et des options sur des recherches non-gourmandes, des recherches multilignes, etc...';
preg_match('`des`', $chaine, $out);

// ou avec ereg
ereg('des',$chaine,$out);

print_r($out);
// affichera : Array ( [0] => des )

// Avec preg_match_all
preg_match_all('`des`', $chaine, $out);

print_r($out);
// affichera : Array ( [0] => Array ( [0] => des [1] => des [2] => des [3] => des [4] => des [5] => des ) )
?>


ADAM Benjamin 2008 | Admin