关闭贪婪不在这个正则表达式

时间:2011-04-15 09:54:03

标签: regex

我正在尝试运行以下搜索(使用。来匹配换行符,方法是在perl中添加/ s标志或在vim中用\_.替换它):

/<output_channels>.*(?=Story).*?<\/output_channels>/

但是?并没有像往常那样关闭贪婪 - 任何人都能解释为什么吗?例如,它匹配以下文件的全部内容,而不仅仅是第一个元素:

<output_channels>
  <output_channel>RSS</output_channel>
  <output_channel>Story</output_channel> 
</output_channels>

<output_channels>
  <output_channel>RSS</output_channel>
</output_channels>

很抱歉,如果我遗漏了一些明显的东西。

2 个答案:

答案 0 :(得分:1)

正则表达式中的第一个.*仍然是贪婪的。您只在第二个之后添加了?

答案 1 :(得分:1)

我将您的示例文本放入vim缓冲区,然后执行命令

:%!perl -e '$text = join("", <STDIN>); $text =~ /<output_channels>.*(?=Story).*?<\/output_channels>/s; print $&;'

结果只是XML的第一个块。我想这就是你想要的?

请注意,我在正则表达式中转义了/。除此之外,它与您提出的问题相同。

另请注意,等效的vim RE将(测试,工作):

<output_channels>\_.*\(story\)\@=\_.\{-}<\/output_channels>

请参阅:help perl-patterns了解perl和vim RE之间的差异。

进一步注意parsing heirarchical markup with regexps has been known to reawaken ancient demons