3
echo "$(expr "title: Purple Haze       artist: Jimi Hendrix" : 'title:\s*\(.*\?\)\s*artist.*' )"

印刷

Purple Haze             

使用尾随空格,即使我使用的是?惰性运算符。

我已经在https://regex101.com/上对此进行了测试,它按预期工作,bash 有什么不同?

4

2 回答 2

6

您没有使用 bash 的正则表达式匹配,而是使用expr. expr没有“<code>? 惰性运算符”,它只实现了基本的正则表达式(在 Linux 版本中有一些扩展,例如\s空格,但不包括类似 Perl 的惰性运算符)。(就此而言,bash 也没有。)

如果您不想.*包含尾随空格,请指定它必须以非空格字符结尾:

'title:\s*\(.*\S\)\s*artist.*'
于 2015-01-04T15:23:26.840 回答
2

正如 Gilles 指出的那样,您没有使用 bash 正则表达式。为此,您可以=~像这样使用正则表达式匹配运算符:

re='title:[[:space:]]*(.*[^[:space:]])[[:space:]]*artist.*'
details='title: Purple Haze       artist: Jimi Hendrix'
[[ $details =~ $re ]] && echo "${BASH_REMATCH[1]}"

这不是使用惰性匹配,而是在捕获组的末尾使用非空格字符,因此删除了尾随空格。第一个捕获组存储在${BASH_REMATCH[1]}.

以牺牲跨平台可移植性为代价,也可以使用简写\sand\S代替[[:space:]]and [^[:space:]]

re='title:\s*(.*\S)\s*artist.*'
于 2015-01-04T15:28:47.567 回答