it-swarm-eu.dev

Comment puis-je valider l'expression régulière?

Je voudrais tester la validité d'une expression régulière en PHP, de préférence avant son utilisation. La seule façon de le faire est-elle d'essayer une preg_match() et de voir si elle retourne FALSE?

Existe-t-il un moyen plus simple/approprié de tester une expression régulière valide?

65
Ross McFarlane
// This is valid, both opening ( and closing )
var_dump(preg_match('~Valid(Regular)Expression~', null) === false);
// This is invalid, no opening ( for the closing )
var_dump(preg_match('~InvalidRegular)Expression~', null) === false);

Comme l'a dit l'utilisateur pozs, aussi pensez à mettre @ Devant preg_match () (@preg_match()) dans un environnement de test pour éviter avertissements ou avis.

Pour valider un RegExp il suffit de l'exécuter contre null (pas besoin de connaître les données que vous souhaitez tester par rapport à l'avance) . S'il retourne explicitement false (=== false), Il est cassé. Sinon, il est valide, mais il ne doit rien correspondre.

Il n'est donc pas nécessaire d'écrire votre propre validateur RegExp. C'est du temps perdu ...

125
CodeAngry

J'ai créé une fonction simple qui peut être appelée pour vérifier preg

function is_preg_error()
{
    $errors = array(
        PREG_NO_ERROR               => 'Code 0 : No errors',
        PREG_INTERNAL_ERROR         => 'Code 1 : There was an internal PCRE error',
        PREG_BACKTRACK_LIMIT_ERROR  => 'Code 2 : Backtrack limit was exhausted',
        PREG_RECURSION_LIMIT_ERROR  => 'Code 3 : Recursion limit was exhausted',
        PREG_BAD_UTF8_ERROR         => 'Code 4 : The offset didn\'t correspond to the begin of a valid UTF-8 code point',
        PREG_BAD_UTF8_OFFSET_ERROR  => 'Code 5 : Malformed UTF-8 data',
    );

    return $errors[preg_last_error()];
}

Vous pouvez appeler cette fonction en utilisant le code suivant:

preg_match('/(?:\D+|<\d+>)*[!?]/', 'foobar foobar foobar');
echo is_preg_error();

Alternative - Testeur en ligne d'expressions régulières

22
Wahyu Kristianto

Si vous voulez tester dynamiquement une expression régulière, preg_match(...) === false semble être votre seule option. PHP n'a pas de mécanisme pour compiler les expressions régulières avant leur utilisation.

Vous pouvez également trouver preg_last_error une fonction utile.

D'un autre côté, si vous avez une expression régulière et que vous voulez simplement savoir si elle est valide avant de l'utiliser, il existe un tas d'outils disponibles. J'ai trouvé rubular.com agréable à utiliser.

15
Alin Purcaru

Vous pouvez vérifier si c'est une regex syntaxiquement correcte avec ce cauchemar d'une regex, si votre moteur prend en charge la récursivité (PHP devrait).

Cependant, vous ne pouvez pas dire par algorithme s'il donnera les résultats souhaités sans l'exécuter.

De: Existe-t-il une expression régulière pour détecter une expression régulière valide?

/^((?:(?:[^?+*{}()[\]\\|]+|\\.|\[(?:\^?\\.|\^[^\\]|[^\\^])(?:[^\]\\]+|\\.)*\]|\((?:\?[:=!]|\?<[=!]|\?>)?(?1)??\)|\(\?(?:R|[+-]?\d+)\))(?:(?:[?+*]|\{\d+(?:,\d*)?\})[?+]?)?|\|)*)$/
6
evandentremont

Sans réellement exécuter l'expression régulière, vous n'avez aucun moyen de vous assurer qu'elle est valide. J'ai récemment implémenté un RegexValidator similaire pour Zend Framework. Fonctionne très bien.

<?php
class Nuke_Validate_RegEx extends Zend_Validate_Abstract
{
    /**
     * Error constant
     */
    const ERROR_INVALID_REGEX = 'invalidRegex';

    /**
     * Error messages
     * @var array
     */
    protected $_messageTemplates = array(
        self::ERROR_INVALID_REGEX => "This is a regular expression PHP cannot parse.");

    /**
     * Runs the actual validation
     * @param string $pattern The regular expression we are testing
     * @return bool
     */
    public function isValid($pattern)
    {
        if (@preg_match($pattern, "Lorem ipsum") === false) {
            $this->_error(self::ERROR_INVALID_REGEX);
            return false;
        }
        return true;
    }
}
2
ChrisR

Je ne sais pas s'il prend en charge PCRE, mais il existe une extension Chrome sur https://chrome.google.com/webstore/detail/cmmblmkfaijaadfjapjddbeaoffeccib appelée - RegExp Tester . Je ne l'ai pas encore utilisé moi-même donc je ne peux pas en garantir, mais peut-être qu'il pourrait être utile?

1
Tash Pemhiwa

Vous pouvez valider votre expression régulière avec une expression régulière et jusqu'à une certaine limite. Checkout this stack overflow answer pour plus d'informations.

Remarque: une "expression régulière récursive" n'est pas une expression régulière, et cette version étendue de regex ne correspond pas aux expressions régulières.

Une meilleure option consiste à utiliser preg_match et match contre NULL en tant que @Claudrian said

1
rajukoyilandy

Donc en résumé, pour tous ceux qui viennent à cette question, vous pouvez valider les expressions régulières dans PHP avec une fonction comme celle-ci.

preg_match () renvoie 1 si le motif correspond au sujet donné, 0 si ce n'est pas le cas, ou FALSE si une erreur s'est produite. - Manuel PHP

/**
 * Return an error message if the regular expression is invalid
 *
 * @param string $regex string to validate
 * @return string
 */
function invalidRegex($regex)
{
    if(preg_match($regex, null) !== false)
    {
        return '';
    }

    $errors = array(
        PREG_NO_ERROR               => 'Code 0 : No errors',
        PREG_INTERNAL_ERROR         => 'Code 1 : There was an internal PCRE error',
        PREG_BACKTRACK_LIMIT_ERROR  => 'Code 2 : Backtrack limit was exhausted',
        PREG_RECURSION_LIMIT_ERROR  => 'Code 3 : Recursion limit was exhausted',
        PREG_BAD_UTF8_ERROR         => 'Code 4 : The offset didn\'t correspond to the begin of a valid UTF-8 code point',
        PREG_BAD_UTF8_OFFSET_ERROR  => 'Code 5 : Malformed UTF-8 data',
    );

    return $errors[preg_last_error()];
}

Qui peut être utilisé comme ça.

if($error = invalidRegex('/foo//'))
{
    die($error);
}
1
Xeoncross

Je serais enclin à mettre en place un certain nombre de tests unitaires pour votre regex. De cette façon, non seulement vous seriez en mesure de vous assurer que l'expression régulière est bien valide mais également efficace pour l'appariement.

Je trouve que l'utilisation de TDD est un moyen efficace de développer l'expression régulière et signifie que son extension à l'avenir est simplifiée car vous avez déjà tous vos cas de test disponibles.

La réponse à cette question a une excellente réponse sur la configuration de vos tests unitaires.

0
Rob Forrest

Vous devez essayer de faire correspondre l'expression régulière à NULL. Si le résultat est FAUX (=== FALSE), Il y avait une erreur.

Dans PHP> = 5.5, vous pouvez utiliser ce qui suit pour obtenir automatiquement le message d'erreur intégré, sans avoir besoin de définir votre propre fonction pour l'obtenir:

preg_match($regex, NULL);
echo array_flip(get_defined_constants(true)['pcre'])[preg_last_error()];
0
mbomb007