代码之家  ›  专栏  ›  技术社区  ›  fadedbee

Bash regex与预期不匹配[duplicate]

  •  0
  • fadedbee  · 技术社区  · 7 年前

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

    作品。但是,如果我试图在正则表达式中使用引号,它会停止:

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

    我试过了 "\[0-9\]"

    bash advanced scripting guide 建议这应该行得通。

    Bash版本3.2.39。

    0 回复  |  直到 8 年前
        1
  •  114
  •   Vinko Vrsalovic    17 年前

    between 3.1 and 3.2 . 我猜高级指南需要更新。

    自 bash-3.1的发布。一如既往 手册页(doc/bash.1)就是这个地方 寻找完整的描述。

    剪

    f、 将字符串参数引用到 [[command's=~操作员现在强制 字符串匹配,与其他模式匹配运算符一样。

    遗憾的是,这将破坏使用脚本的现有引用,除非您有在变量中存储模式并直接使用它们而不是正则表达式的洞察力。示例如下。

    $ 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
    
        2
  •  21
  •   Nicholas Sushkin    15 年前

    bash3.2引入了一个兼容性选项compat31,它将Bash正则表达式引用行为还原为3.1

    没有兼容31:

    $ 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
    

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

    链接到修补程序: http://ftp.gnu.org/gnu/bash/bash-3.2-patches/bash32-039

        3
  •  7
  •   Ankur Agarwal    10 年前

    GNU bash,版本4.2.25(1)-发布(x86_64-pc-linux-GNU)

    字符串匹配和正则表达式匹配的一些示例

        $ 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
    
        4
  •  5
  •   Digital Trauma    12 年前

    正如其他答案中提到的,将正则表达式放在变量中是实现不同类型的兼容性的一般方法 版本。您也可以使用此解决方法来实现相同的功能,同时将正则表达式保留在条件表达式中:

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