bash正则表达式的多个匹配行为奇怪吗?

时间:2014-10-28 03:03:31

标签: regex bash xml-parsing

string="<tag>First Tag</tag>Some random text <tag>Second Tag</tag>More random text<tag>Third Tag</tag>"

pattern='<tag>(.*?)<\/tag>' 

if [[ $string =~ $pattern ]]; then 
    parsedMatch=${BASH_REMATCH[1]}
    echo -e "$parsedMatch"
fi

Output : First Tag</tag>Some random text <tag>Second Tag</tag>More random text<tag>Third Tag

Expected output : <tag>First Tag</tag>

在此示例中,BASH_REMATCH [0]和BASH_REMATCH [1]都相同。 我知道其他正则表达式库,但我很困惑为什么这样做?

编辑:更改了模式以使其不合适但仍然无法正常工作。此行为仅存在于linux / bash中,因此您需要在那里进行测试。

3 个答案:

答案 0 :(得分:0)

它表现如此,因为.*在模式匹配中贪婪并且尽可能匹配。

所以使用其他正则表达式

(<tag>[^<]*</tag>)


string="<tag>First Tag</tag>Some random text <tag>Second Tag</tag>More random text<tag>Third Tag</tag>"

pattern='(<tag>[^<]*</tag>)'

if [[ $string =~ $pattern ]]; then
    parsedMatch=${BASH_REMATCH[1]}
    echo -e "$parsedMatch"
fi

将输出生成为

<tag>First Tag</tag>

说明:

<tag>匹配起始<tag>

[^<]*匹配<

以外的任何内容

</tag>匹配结尾</tag>

DEMO

修改

Bash使用POSIX.2正则表达式,它不支持非贪婪的Kleene星

答案 1 :(得分:0)

试试这个会很好用。

使用此正则表达式:<tag(?: [^>]+)?>((?:(?!<\/?tag[ >]).)*)<\/tag>

查看演示: http://regex101.com/r/nC1dO8/2

答案 2 :(得分:0)

你可以用附加的?来控制*的贪婪。默认情况下它贪婪并附加?它不是。因此,请尝试将<tag>(.*?)</tag>作为模式。