为什么不能在bash正则表达式测试中使用字符串文字?

时间:2011-07-12 14:10:19

标签: regex string bash variables literals

为什么以下bash脚本只打印出variable worked

#! /bin/bash

foo=baaz
regex='ba{2}z'

if [[ $foo =~ 'ba{2}z' ]]; then
    echo "literal worked"
fi

if [[ $foo =~ $regex ]]; then
    echo "variable worked"
fi

bash文档中是否有一些内容表明=~运算符仅适用于变量,而不适用于文字?此限制是否适用于任何其他运营商?

2 个答案:

答案 0 :(得分:9)

您不再需要bash正则表达式的引号:

#! /bin/bash

foo=baaz
regex='ba{2}z'

if [[ $foo =~ ba{2}z ]]; then
    echo "literal worked"
fi

if [[ $foo =~ $regex ]]; then
    echo "variable worked"
fi

# Should output literal worked, then variable worked

我不记得哪个版本改变了这个。

答案 1 :(得分:2)

在Bash 3.1之前,您的代码实际上按预期工作。 但是自Bash 3.2以来,模式匹配运算符的行为已经改变。引用最新的Bash Manual

  

“可以引用模式的任何部分以强制它匹配为a   字符串“

这正是这里发生的事情。你的意思是使用{}作为元字符,但是因为你引用它,Bash按字面解释它们。 您有两种选择:

1.您可以使用shopt -s compat31打开3.1兼容模式,如下所示:

#!/bin/bash
shopt -s compat31

foo=baaz
regex='ba{2}z'

if [[ $foo =~ 'ba{2}z' ]]; then
    echo "literal worked"
fi

if [[ $foo =~ $regex ]]; then
    echo "variable worked"
fi

2.您可以通过删除操作员右侧的引文来移植您的代码:

#!/bin/bash

foo=baaz
regex='ba{2}z'

if [[ $foo =~ ba{2}z ]]; then
    echo "literal worked"
fi

if [[ $foo =~ $regex ]]; then
    echo "variable worked"
fi