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.

Était-ce utile?

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.

  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

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 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
$ 
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top