我正在尝试运行以下搜索(使用。来匹配换行符,方法是在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>
很抱歉,如果我遗漏了一些明显的东西。
答案 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。