Il y a deux ou trois choses importantes à savoir à propos de la fonction de bash [[ ]]
construction. La première :
Le découpage des mots et l'expansion des noms de chemin ne sont pas effectués sur les mots situés entre les balises [[
y ]]
; l'expansion du tilde, l'expansion des paramètres et des variables, l'expansion arithmétique, la substitution de commande, la substitution de processus et la suppression des guillemets sont effectuées.
La deuxième chose :
Un opérateur binaire supplémentaire, '=~', est disponible,... la chaîne à droite de l'opérateur est considérée comme une expression régulière étendue et est appariée en conséquence... N'importe quelle partie du motif peut être citée pour le forcer à correspondre à une chaîne de caractères. .
En conséquence, $v
de part et d'autre de la =~
sera étendu à la valeur de cette variable, mais le résultat ne sera pas divisé par des mots ou étendu par des chemins. En d'autres termes, il est parfaitement sûr de laisser les expansions de variables non citées du côté gauche, mais vous devez savoir que les expansions de variables auront lieu du côté droit.
Donc si tu écris : [[ $x =~ [$0-9a-zA-Z] ]]
le $0
à l'intérieur de la regex à droite sera développée avant que la regex soit interprétée, ce qui fera probablement échouer la compilation de la regex (à moins que l'expansion de $0
se termine par un chiffre ou un symbole de ponctuation dont la valeur ascii est inférieure à un chiffre). Si vous citez le côté droit comme [[ $x =~ "[$0-9a-zA-Z]" ]]
alors le côté droit sera traité comme une chaîne ordinaire, et non comme une regex. (et $0
seront encore élargis). Ce que vous voulez vraiment dans ce cas est [[ $x =~ [\$0-9a-zA-Z] ]]
De même, l'expression entre le [[
y ]]
est divisé en mots avant que la regex soit interprétée. Les espaces dans la regex doivent donc être échappés ou cités. Si vous voulez faire correspondre des lettres, des chiffres ou des espaces, vous pouvez utiliser : [[ $x =~ [0-9a-zA-Z\ ] ]]
. D'autres caractères doivent également être échappés, par exemple #
qui lancerait un commentaire s'il n'était pas cité. Bien entendu, vous pouvez placer le motif dans une variable :
pat="[0-9a-zA-Z ]"
if [[ $x =~ $pat ]]; then ...
Pour les regex qui contiennent beaucoup de caractères qui devraient être échappés ou cités pour passer dans le lexer de bash, beaucoup de gens préfèrent ce style. Mais attention : dans ce cas, vous no puede citer l'expansion de la variable :
# This doesn't work:
if [[ $x =~ "$pat" ]]; then ...
Enfin, je pense que ce que vous essayez de faire est de vérifier que la variable ne contient que des caractères valides. La façon la plus simple d'effectuer cette vérification est de s'assurer qu'elle ne contient pas de caractère non valide. En d'autres termes, une expression comme celle-ci :
valid='0-9a-zA-Z $%&#' # add almost whatever else you want to allow to the list
if [[ ! $x =~ [^$valid] ]]; then ...
!
annule le test, en le transformant en un opérateur "ne correspond pas", et l'opérateur [^...]
La classe de caractères regex signifie "tout caractère autre que ...
".
La combinaison de l'expansion des paramètres et des opérateurs regex peut rendre la syntaxe des expressions régulières de bash "presque lisible", mais il y a encore quelques problèmes. (N'y en a-t-il pas toujours ?) L'un d'entre eux est que vous ne pouvez pas mettre ]
en $valid
même si $valid
ont été cités, sauf au tout début. (C'est une règle de regex Posix : si vous voulez inclure ]
dans une classe de personnage, il doit être placé au début. -
peuvent aller au début ou à la fin, donc si vous avez besoin des deux ]
y -
vous devez commencer par ]
et se terminent par -
ce qui a conduit à l'émoticône regex "Je sais ce que je fais" : [][-]
)