[PHP] Comment valider une regexp

WRInaute discret
Bonjour,

Je cherche une fonction qui me permette de savoir si une regexp est valide avant de l'appeller. :?

J'ai un site qui demande à l'utilisateur de rentrer une expression régulière via un formulaire, mais si sa syntaxe n'est pas valide, celà provoque une erreur. Je souhaiterais tester la validité de l'expression avant de l'utiliser.

J'ai cherché désespérément une fonction is_regexp mais elle n'existe pas, également, var_filter renvoie une erreur.

J'ai trouvé une expression régulière pour tester les expressions régulières 8O :
Code:
/^((?:(?:[^?+*{}()[\]\]+|\.|\[(?:[^\]\]+|\.)*\]|\((?:\?[:=!]|\?<[=!]|\?>)?(?1)??\)|\(\?(?:R|[+-]?\d+)\))(?:(?:[?+*]|\{\d+(?:,\d*)?\})[?+]?)?\|?)*)$/
mais sur mon serveur, celle ci renvoie l'erreur : recursive call could loop indefinitely. :(

Merci de vos lumières pour cette énigme.
 
WRInaute accro
Une combinaison de @ en préfixe de ton appel et de preg_last_error peut-être?

Attention cependant à ce que tu autorises comme regex (ça dépend de comment tu l'utilises), tu risques d'ouvrir énormément de trous de sécurité, en particulier si tu utilises preg_replace et que tu laisses le flag "e" passer, mais il y a probablement d'autres failles possibles.

Quel est l'intérêt de laisser cette flexibilité à l'utilisateur?

Jacques.
 
WRInaute discret
Merci pour ta réponse en fait l'utilisation du @ n'évite pas l'erreur, simplement son affichage, seulement j'ai configuré mon serveur pour enregistrer toutes les erreurs, et la page concernant ce regexp est responsable d'une bonne partie de ces erreurs

Il est donc préférable pour moi d'avoir une petite ligne de test. J'ai trouvé un code plutot compliqué mais qui ne me convient pas car il manipule un error_handler, mais ne supprime pas l'erreur.

Code:
function is_regexp( $reg_exp, $includes_delim = false )
{
        $sPREVIOUSHANDLER = set_error_handler( '_trapError' );
        if( ! $includes_delim )
        {
                $reg_exp = '#'.str_replace( '#', '\#', $reg_exp ).'#';
        }
        preg_match( $reg_exp, '' );
        restore_error_handler( $sPREVIOUSHANDLER );

        return !_traperror();
}

Sinon il n'y a pas de problème de sécurité, il s'agit d'un simple preg_match sur une liste de données avec des codes structurés ABCD1234 justifiant l'utilisation du regexp.
 
WRInaute discret
Toujours personne ?

J'ai essayé de passer par var_filter() et la constante FILTER_VALIDATE_REGEXP mais je ne vois pas bien comment il fonctionne, il n'a pas l'air de faire ce que son nom indique...
 
Nouveau WRInaute
Pourquoi ne pas tester tout simplement ta regex et entourer ce test par un bloc try catch ?

En cas de "catch", la regex est fausse, sinon, elle est bonne.
 
WRInaute discret
Imaginons que je veux tester avec preg_match($regexp, '');
la fonction preg_match ne gènère pas d'exception, si ?
 
WRInaute discret
J'ai beau tester dans tous les sens, et même en utilisant ton code, PHP retourne une erreur :

Erreur [2] preg_match() [function.preg-match]: Compilation failed: nothing to repeat at offset 3

La valeur de l'erreur est de type : 2 E_WARNING
 
Discussions similaires
Haut