Pregunta

El siguiente código

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

obras.Sin embargo, si intento usar comillas en la expresión regular, se detiene:

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

Lo intenté "\[0-9\]", también.¿Qué me estoy perdiendo?

Curiosamente, guía de scripting avanzado de bash sugiere que esto debería funcionar.

Versión de bash 3.2.39.

¿Fue útil?

Solución

Fue cambiado entre 3,1 y 3,2.Supongo que la guía avanzada necesita una actualización.

Esta es una descripción breve de las nuevas características agregadas a Bash-3.2 desde el lanzamiento de Bash-3.1.Como siempre, la página manual (doc/bash.1) es el lugar para buscar descripciones completas.

  1. Nuevas funciones en Bash

recorte

F.Citando el argumento de cadena en el operador [[comandante = ~ ahora fuerza la coincidencia de cadenas, como con los otros operadores de coincidencia de patrones.

Lamentablemente, esto romperá las cotizaciones existentes mediante scripts a menos que tenga la idea de almacenar patrones en variables y usarlos en lugar de las expresiones regulares directamente.Ejemplo a continuación.

$ 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

Otros consejos

Bash 3.2 introdujo una opción de compatibilidad compat31 que revierte el comportamiento de citación de expresiones regulares de bash a 3.1

Sin 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

Con 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

Enlace al parche:http://ftp.gnu.org/gnu/bash/bash-3.2-patches/bash32-039

GNU bash, versión 4.2.25(1) (x86_64-pc-linux-gnu)

Algunos ejemplos de coincidencia de cadenas y de expresiones regulares

    $ 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

Como se mencionó en otras respuestas, poner la expresión regular en una variable es una forma general de lograr compatibilidad entre diferentes versiones.También puede utilizar esta solución alternativa para lograr lo mismo, manteniendo su expresión regular dentro de la expresión condicional:

$ number=1
$ if [[ $number =~ $(echo "[0-9]") ]]; then echo matched; fi
matched
$ 
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top