bash regex with quotes? bash regex with quotes? bash bash

bash regex with quotes?


It was changed between 3.1 and 3.2. Guess the advanced guide needs an update.

This is a terse description of the new features added to bash-3.2 since the release of bash-3.1. As always, the manual page (doc/bash.1) is the place to look for complete descriptions.

  1. New Features in Bash

snip

f. Quoting the string argument to the [[ command's =~ operator now forces string matching, as with the other pattern-matching operators.

Sadly this'll break existing quote using scripts unless you had the insight to store patterns in variables and use them instead of the regexes directly. Example below.

$ bash --versionGNU 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; fimatch$ re="[0-9]"$ if [[ $number =~ $re ]]; then echo MATCH; fiMATCH$ bash --versionGNU 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; fimatch$ if [[ "$number" =~ [0-9] ]]; then echo match; fimatch


Bash 3.2 introduced a compatibility option compat31 which reverts bash regular expression quoting behavior back to 3.1

Without compat31:

$ shopt -u compat31$ shopt compat31compat31        off$ set -x$ if [[ "9" =~ "[0-9]" ]]; then echo match; else echo no match; fi+ [[ 9 =~ \[0-9] ]]+ echo no matchno match

With compat31:

$ shopt -s compat31+ shopt -s compat31$ if [[ "9" =~ "[0-9]" ]]; then echo match; else echo no match; fi+ [[ 9 =~ [0-9] ]]+ echo matchmatch

Link to 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)

Some examples of string match and 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