78 votes

bash regex avec des guillemets?

Le code suivant

 number=1
if [[ $number =~ [0-9] ]]
then
  echo matched
fi
 

travaux. Si j'essaie d'utiliser des guillemets dans la regex, cela s'arrête:

 number=1
if [[ $number =~ "[0-9]" ]]
then
  echo matched
fi
 

J'ai aussi essayé "\ [0-9 \]". Qu'est-ce que je rate?

Curieusement, le guide de script avancé de bash suggère que cela devrait fonctionner.

Bash version 3.2.39.

119voto

Vinko Vrsalovic Points 116138

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.

  1. 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

21voto

Nicholas Sushkin Points 922

Bash 3.2 a introduit une option de compatibilité compat31 qui rétablit le comportement des expressions régulières bash en 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 correctif: http://ftp.gnu.org/gnu/bash/bash-3.2-patches/bash32-039

8voto

abc Points 2888

GNU bash, version 4.2.25 (1) - release (x86_64-pc-linux-gnu)

Quelques exemples de correspondance de chaîne et de correspondance regex

     $ 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

    ankura@u782bcba799915202a02b:~$ 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
 

5voto

DigitalTrauma Points 6235

Comme indiqué dans d'autres réponses, le fait de placer l'expression régulière dans une variable constitue un moyen général d'assurer la compatibilité entre différentes versions de . Vous pouvez également utiliser cette solution de contournement pour obtenir la même chose, tout en conservant votre expression régulière dans l'expression conditionnelle:

 $ number=1
$ if [[ $number =~ $(echo "[0-9]") ]]; then echo matched; fi
matched
$ 
 

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