【问题标题】:Matching brackets inside a regular expression does not work in bash正则表达式中的匹配括号在 bash 中不起作用
【发布时间】:2019-11-22 07:55:00
【问题描述】:

我定义了一个函数,如果它的第一个参数包含abc,则打印yes

$ func() { [[ $1 =~ [abc] ]] && echo yes; }
$ func xyz
$ func xaz
yes
$ func xbz
yes
$ func xcz
yes

现在我想检测[]*,所以我尝试了:

func() { [[ $1 =~ [\[\]*] ]] && echo yes; }
$ func x*z
$ func x[z
$ func x]z
yes

这似乎只适用于]。我还尝试set -f 禁用全局扩展,但得到了相同的结果。

【问题讨论】:

    标签: bash function arguments glob


    【解决方案1】:

    POSIX 正则表达式规范的BRE/ERE Bracketed Expression 部分很好地解释了该行为:

    1. [...] 如果右括号 (']') 出现在列表的第一个位置,则右括号 (']') 将失去其特殊含义并在括号表达式中表示自己(在初始抑扬符 ('^') 之后,如果有的话) .否则,它将终止括号表达式,除非它出现在整理符号中

    这意味着,您的] 需要出现在括号表达式的开头,可能在^ 之后,而不是表达式后面的任何地方。这是一种特殊情况,仅适用于],但不适用于[,它在括号表达式中丢失了其特殊字符。

    所以定义

    [[ $1 =~ [][*] ]]
    

    应该按预期工作,因为开头的] 没有终止括号表达式。在这里禁用 glob 扩展无关紧要,因为括号表达式中的 * 没有特殊含义,仅按字面意思处理。

    【讨论】:

    • 这澄清了我的问题并使模式更清晰(无需使用反斜杠转义)。
    • 我认为需要禁用 glob。如果当前目录中有以a开头的文件,那么func a*将检测不到*
    • @sergio:我的意思是括号表达式中匹配的*。对于 arg 传递 yes 是必需的,或者字符串可以在引号 a*b 下传递
    【解决方案2】:

    找到了解决方案,但我不知道为什么旧模式不起作用:

    func() { [[ $1 =~ [\]\[*] ]] && echo yes; }
    

    我将模式[\[\]*] 更改为[\]\[*]

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-07-01
      • 2023-04-06
      • 1970-01-01
      • 2015-06-23
      • 2011-08-03
      相关资源
      最近更新 更多