2014-10-28 50 views
0
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]都是相同的。 我知道其他正则表达式库,但我为什么这样表现这个方式感到困惑?bash正则表达式的多个匹配行为奇怪?

编辑:更改模式,使其不合格,它仍然无法正常工作。这种行为只存在于linux/bash中,所以你需要在那里测试它。

回答

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正则表达式,不支持非贪婪克林星

+0

如果存在嵌套标记,则您的正则表达式不匹配。 – 2014-10-28 07:28:53

+0

@RamboRamon它不会但它适合字符串OP提供 – nu11p01n73R 2014-10-28 08:24:54

+0

Nvm这个作品! – user3081457 2014-10-28 11:08:39

0

试试这个会很好。

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

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

+0

感谢您的回复,但您应该在linux/bash终端中尝试它,因为您会得到不同的结果。 – user3081457 2014-10-28 11:07:11

+0

好的,谢谢我在windows中使用。 – depsai 2014-10-28 11:26:33

0

您可以控制的*的greedyness带有附加?默认情况下,它是贪婪的并且附加了?不是这样。所以请尝试<tag>(.*?)</tag>作为模式。

+0

试过了,仍然是相同的输出。 – user3081457 2014-10-28 11:06:01