Bash脚本,if语句中的正则表达式

时间:2014-02-07 12:55:04

标签: regex bash

我很擅长bash脚本和regexp并且有一个问题。 我想查看我的变量$name是否以a-d,e-h,i-l等开头,并相应地做一些事情。如果字符串以“the”开头。或者。”它应该检查一段时间后的第一个字母。

我的问题是,如果$name由“the.anchor”组成,则a-d0-9和q-t都为真。你们有什么问题吗?

if [[ $name =~ ^([tT]he\.)?[a-dA-D0-9]+ ]]; then
    do some stuff
fi

if [[ $name =~ ^([tT]he\.)?[e-hE-H]+ ]]; then
    do some stuff
fi

if [[ $name =~ ^([tT]he\.)?[i-lI-L]+ ]]; then
    do some stuff
fi

if [[ $name =~ ^([tT]he\.)?[m-pM-P]+ ]]; then
    do some stuff
fi

if [[ $name =~ ^([tT]he\.)?[q-tQ-T]+ ]]; then
    do some stuff
fi

if [[ $name =~ ^([tT]he\.)?[u-wU-W]+ ]]; then
    do some stuff
fi

if [[ $name =~ ^([tT]he\.)?[x-zX-Z]+ ]]; then
    do some stuff
fi

提前致谢!

3 个答案:

答案 0 :(得分:2)

你的第一部分是可选的:

([tT]he\.)?

所以the.anchor与模式^([tT]he\.)?[a-dA-D0-9]+匹配,因为the.匹配`^([tT]he\.)?a匹配[a-dA-D0-9]+。它与^([tT]he\.)?[q-tQ-T]+匹配,因为^([tT]he\.)?是可选的,t匹配[q-tQ-T]+。注意不是第二个模式消耗了整个输入,实际上只抓取了第一个字符。

您可以通过bash回显匹配来验证这一点:

echo "${BASH_REMATCH[0]}"

哪个应该在第一种情况下打印the.anchor,在第二种情况下打印t

您在模式上没有结束锚点,因此只需要匹配部分输入。如果您创建了第二个模式^([tT]he\.)?[q-tQ-T]+$,则它将不匹配。

或者你可以使第一部分占有欲 - ^([tT]he\.)?+。这意味着如果引擎匹配第一个表达式,它将不会是不匹配的。在后一种情况下,^([tT]he\.)?+将抓取the.,然后在[q-tQ-T]+失败时不释放它;这会导致比赛失败。

答案 1 :(得分:0)

我找到了一种方法来解决我的问题,使用elif语句并将q-t部分作为最后一个

答案 2 :(得分:0)

我认为可以删除?,因为if语句已经在进行测试。 +至少匹配前一项,只有当您想要匹配多个字母实例时才需要。

你可以这样做:

if [[ $name =~ ^[tT]he\.[a-dA-D0-9] ]]; then
    do some stuff
fi

如果^[tT]he\.之后的第一个字符为[a-dA-D0-9],则该条件才会返回true。

但是,在将字符列表与变量匹配时,我倾向于认为caseif语句更清晰。

case $name in
    [tT]he\.[a-dA-D0-9]*)
        do some stuff
        ;;
esac