bash regex avec des guillemets?
Question
Le code suivant
number=1
if [[ $number =~ [0-9] ]]
then
echo matched
fi
des œuvres.Si j'essaie d'utiliser les citations dans les regex, toutefois, il s'arrête:
number=1
if [[ $number =~ "[0-9]" ]]
then
echo matched
fi
J'ai essayé "\[0-9\]"
, trop.Ce qui me manque?
Curieusement, bash scripting avancé guide suggère cela devrait fonctionner.
Bash version 3.2.39.
La solution
Il a été changé entre 3.1 et 3.2.Deviner le guide avancé nécessite une mise à jour.
C'est un laconique description de la nouvelle fonctionnalités ajoutées à la bash-3.2 depuis le version de bash-3.1.Comme toujours, l' page de manuel (doc/bash.1) est l'endroit pour chercher des descriptions complètes.
- Nouvelles Fonctionnalités de Bash
snip
f.Citant l'argument de chaîne à l' [[ commande =~ exploitant les forces de correspondance de chaîne, comme avec les autres "pattern-matching" des opérateurs.
Malheureusement, cela va casser le devis existant à l'aide de scripts sauf si vous avez eu la perspicacité de stocker des patterns dans les variables et les utiliser au lieu de les regexes directement.L'exemple ci-dessous.
$ bash --version
GNU bash, version 3.2.39(1)-release (i486-pc-linux-gnu)
Copyright (C) 2007 Free Software Foundation, Inc.
$ number=2
$ if [[ $number =~ "[0-9]" ]]; then echo match; fi
$ if [[ $number =~ [0-9] ]]; then echo match; fi
match
$ re="[0-9]"
$ if [[ $number =~ $re ]]; then echo MATCH; fi
MATCH
$ bash --version
GNU bash, version 3.00.0(1)-release (i586-suse-linux)
Copyright (C) 2004 Free Software Foundation, Inc.
$ number=2
$ if [[ $number =~ "[0-9]" ]]; then echo match; fi
match
$ if [[ "$number" =~ [0-9] ]]; then echo match; fi
match
Autres conseils
Bash 3.2 introduit une option de compatibilité compat31 qui revient bash expression régulière citant le comportement de retour à la 3.1
Sans compat31:
$ shopt -u compat31
$ shopt compat31
compat31 off
$ set -x
$ if [[ "9" =~ "[0-9]" ]]; then echo match; else echo no match; fi
+ [[ 9 =~ \[0-9] ]]
+ echo no match
no match
Avec compat31:
$ shopt -s compat31
+ shopt -s compat31
$ if [[ "9" =~ "[0-9]" ]]; then echo match; else echo no match; fi
+ [[ 9 =~ [0-9] ]]
+ echo match
match
Lien vers le patch:http://ftp.gnu.org/gnu/bash/bash-3.2-patches/bash32-039
GNU bash, version 4.2.25(1)-release (x86_64-pc-linux-gnu)
Quelques exemples de correspondance de chaînes et de regex match
$ if [[ 234 =~ "[0-9]" ]]; then echo matches; fi # string match
$
$ if [[ 234 =~ [0-9] ]]; then echo matches; fi # regex natch
matches
$ var="[0-9]"
$ if [[ 234 =~ $var ]]; then echo matches; fi # regex match
matches
$ if [[ 234 =~ "$var" ]]; then echo matches; fi # string match after substituting $var as [0-9]
$ if [[ 'rss$var919' =~ "$var" ]]; then echo matches; fi # string match after substituting $var as [0-9]
$ if [[ 'rss$var919' =~ $var ]]; then echo matches; fi # regex match after substituting $var as [0-9]
matches
$ if [[ "rss\$var919" =~ "$var" ]]; then echo matches; fi # string match won't work
$ if [[ "rss\\$var919" =~ "$var" ]]; then echo matches; fi # string match won't work
$ if [[ "rss'$var'""919" =~ "$var" ]]; then echo matches; fi # $var is substituted on LHS & RHS and then string match happens
matches
$ if [[ 'rss$var919' =~ "\$var" ]]; then echo matches; fi # string match !
matches
$ if [[ 'rss$var919' =~ "$var" ]]; then echo matches; fi # string match failed
$
$ if [[ 'rss$var919' =~ '$var' ]]; then echo matches; fi # string match
matches
$ echo $var
[0-9]
$
$ if [[ abc123def =~ "[0-9]" ]]; then echo matches; fi
$ if [[ abc123def =~ [0-9] ]]; then echo matches; fi
matches
$ if [[ 'rss$var919' =~ '$var' ]]; then echo matches; fi # string match due to single quotes on RHS $var matches $var
matches
$ if [[ 'rss$var919' =~ $var ]]; then echo matches; fi # Regex match
matches
$ if [[ 'rss$var' =~ $var ]]; then echo matches; fi # Above e.g. really is regex match and not string match
$
$ if [[ 'rss$var919[0-9]' =~ "$var" ]]; then echo matches; fi # string match RHS substituted and then matched
matches
$ if [[ 'rss$var919' =~ "'$var'" ]]; then echo matches; fi # trying to string match '$var' fails
$ if [[ '$var' =~ "'$var'" ]]; then echo matches; fi # string match still fails as single quotes are omitted on RHS
$ if [[ \'$var\' =~ "'$var'" ]]; then echo matches; fi # this string match works as single quotes are included now on RHS
matches
Comme mentionné dans d'autres réponses, en mettant l'expression régulière dans une variable est d'une manière générale, pour assurer la compatibilité sur les différents bash les versions.Vous pouvez également utiliser cette solution de contournement pour obtenir la même chose, tout en gardant votre expression régulière à l'intérieur de l'expression conditionnelle:
$ number=1
$ if [[ $number =~ $(echo "[0-9]") ]]; then echo matched; fi
matched
$