42 votes

Que signifie la regex "[^][]" ?

Je l'ai trouvé dans la regex suivante :

\[(?:[^][]|(?R))*\]

Il fait correspondre les crochets (avec leur contenu) avec les crochets imbriqués.

69voto

Casimir et Hippolyte Points 33449

[^][] est une classe de caractères qui désigne tous les caractères à l'exception de [ y ] .

Vous pouvez éviter d'échapper [ y ] les caractères spéciaux car ils ne sont pas ambigus pour le PCRE, le moteur d'expressions rationnelles utilisé dans les systèmes d'information de l'UE. preg_ fonctions.

Depuis [^] est incorrecte dans PCRE, la seule façon pour la regex d'être analysée est que ] se trouve dans la classe de caractères qui sera fermée plus tard. Il en va de même pour le [ qui suit. Il ne peut pas rouvrir une classe de caractères (sauf une classe de caractères POSIX [:alnum:] ) à l'intérieur d'une classe de caractères. Ensuite, le dernier ] est clair : il s'agit de la fin de la classe de caractères. Cependant, un [ en dehors d'une classe de caractères doit être échappé car il est interprété comme le début d'une classe de caractères.

De la même manière, vous pouvez écrire []] o [[] o [^[] sans échapper à la [ o ] dans la classe de caractères.

Note : depuis PHP 7.3, vous pouvez utiliser le modificateur inline xx qui permet d'ignorer les caractères vides même à l'intérieur des classes de caractères. De cette manière, vous pouvez écrire ces classes d'une manière moins ambiguë : (?xx) [^ ][ ] [ ] ] [ [ ] [^ [ ] .

Vous pouvez utiliser cette syntaxe avec plusieurs saveurs de regex : PCRE (PHP, R), Perl, Python, Java, .NET, GO, awk, Tcl ( si vous délimitez votre modèle avec des crochets, merci Donal Fellows ), ...

Mais pas avec : Ruby, JavaScript ( sauf pour IE < 9 ), ...

Comme l'a noté m.buettner, [^]] n'est pas ambiguë car ] est le premier caractère, [^a]] est considéré comme tout ce qui n'est pas un a suivi d'un ] . Pour avoir a y ] vous devez écrire : [^a\]] o [^]a]

Dans le cas particulier de JavaScript, la spécification permet [] sous la forme d'une expression rationnelle qui jamais (en d'autres termes, [] échouera toujours) et [^] comme une expression rationnelle qui correspond à tout caractère . Ensuite [^]] est considéré comme tout caractère suivi d'un ] . La mise en œuvre réelle varie, mais les navigateurs modernes s'en tiennent généralement à la définition de la spécification.

Détails du motif :

\[          # literal [
(?:         # open a non capturing group
    [^][]   # a character that is not a ] or a [
  |         # OR
    (?R)    # the whole pattern (here is the recursion)
)*          # repeat zero or more time
\]          # a literal ]

Dans votre exemple, vous n'avez pas besoin d'échapper le dernier mot de la phrase ]

Mais vous pouvez faire la même chose avec ce modèle un peu optimisé, et plus utile car réutilisable en tant que sous-modèle. (avec le (?-1) ) : (\[(?:[^][]+|(?-1))*+])

(                     # open the capturing group
    \[                # a literal [
        (?:           # open a non-capturing group
            [^][]+    # all characters but ] or [ one or more time
          |           # OR
            (?-1)     # the last opened capturing group (recursion)
                      # (the capture group where you are)
        )*+           # repeat the group zero or more time (possessive)
    ]                 # literal ] (no need to escape)
)                     # close the capturing group

ou mieux : (\[[^][]*(?:(?-1)[^][]*)*+]) qui évite le coût d'une alternance.

29 votes

... mais vous devrait échappez ces caractères spéciaux car cela perturbe la personne chargée de la maintenance de votre code :) Les auteurs de regex ont tendance à aimer le code "délicat" (je m'en suis rendu coupable), mais un code délicat est un code difficile à comprendre.

3 votes

Notez que le point important ici est que ] est le premier caractère (après la négation), car les classes vides ne sont pas autorisées.

11 votes

@cdhowie : Surtout si vous travaillez aussi en JavaScript où [^] est une expression rationnelle valide (signifiant "tout caractère")

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X