echo "$(expr "title: Purple Haze artist: Jimi Hendrix" : 'title:\s*\(.*\?\)\s*artist.*' )"
打印
Purple Haze
使用尾随空格,即使我使用的是?
懒惰运算符。
我已在https://regex101.com/对此进行了测试,并且按预期工作,bash有什么不同?
答案 0 :(得分:6)
您没有使用bash的正则表达式匹配,而是使用expr
。 expr
没有“?
懒惰运算符”,它只实现basic regular expressions(在Linux版本中有一些扩展名,例如\s
用于空格,但这不是不包括类似Perl的懒惰运算符。 (就此而言,bash也没有。)
如果您不希望.*
包含尾随空格,请指明它必须以不是空格的字符结尾:
'title:\s*\(.*\S\)\s*artist.*'
答案 1 :(得分:2)
As Gilles points out,你没有使用bash正则表达式。为此,您可以使用正则表达式匹配运算符=~
,如下所示:
re='title:[[:space:]]*(.*[^[:space:]])[[:space:]]*artist.*'
details='title: Purple Haze artist: Jimi Hendrix'
[[ $details =~ $re ]] && echo "${BASH_REMATCH[1]}"
这不是使用延迟匹配,而是在捕获组的末尾使用非空格字符,因此删除了尾随空格。第一个捕获组存储在${BASH_REMATCH[1]}
。
以牺牲跨平台可移植性为代价,也可以使用简写\s
和\S
代替[[:space:]]
和[^[:space:]]
:
re='title:\s*(.*\S)\s*artist.*'