所以我有这个代码
function test(){
local output="ASD[test]"
if [[ "$output" =~ ASD\[(.*?)\] ]]; then
echo "success";
else
echo "fail"
fi;
}
正如你可以看到它应该回应成功,因为字符串匹配正则表达式。然而,最终返回失败。我做错了什么?
答案 0 :(得分:4)
?
中的ASD\[(.*?)\]
并不属于那里。您似乎正在尝试将非贪婪修饰符应用于*
,这是Perl兼容语法中的*?
,但Bash并不支持这一点。 (请参阅指南here。)事实上,如果您在考试后检查$?
,您会发现它不是1(正常"字符串没有&# 39; t匹配"结果)但是2,表示正则表达式中的语法错误。
如果您使用更简单的模式ASD\[(.*)\]
,则匹配将成功。但是,如果您对可能具有更高括号实例的字符串使用该正则表达式,则括号将捕获太多正则表达式。例如:
output=ASD[test1],ASD[test2]
[[ $output =~ ASD\[(.*)\] ]] && echo "first subscript is '${BASH_REMATCH[1]}'"
#=> first subscript is 'test1],ASD[test2'
在支持*?
语法的语言中,它使匹配"非贪婪"这样它就可以匹配最小的字符串,使整个匹配成功;如果没有?
,这些表达式总是匹配最长的表达式。由于Bash没有非贪婪,你最好的选择可能是使用一个匹配所有的字符类,除了一个关闭括号,使得匹配不可能越过第一个:
[[ $output =~ ASD\[([^]]*)\] ]] && echo "first subscript is '${BASH_REMATCH[1]}'"
#=> first subscript is 'test1'
请注意,如果下标括号中有任何嵌套的支架对层,则会中断 - 但*?
版本也是如此。