Je l'ai trouvé dans la regex suivante :
\[(?:[^][]|(?R))*\]
Il fait correspondre les crochets (avec leur contenu) avec les crochets imbriqués.
Je l'ai trouvé dans la regex suivante :
\[(?:[^][]|(?R))*\]
Il fait correspondre les crochets (avec leur contenu) avec les crochets imbriqués.
[^][]
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.
... 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.
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.
@cdhowie : Surtout si vous travaillez aussi en JavaScript où [^]
est une expression rationnelle valide (signifiant "tout caractère")
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.