2011-04-15 38 views
3

我試圖運行下面的搜索不工作(加上一些以匹配換行符通過添加在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

那麼,你使用Perl的正則表達式或vim的正則表達式搜索/替換? – BoltClock 2011-04-15 09:54:42

+0

你給的RE使用了幾個在vim中不起作用的元素。不知道你是否意識到這一點。檢查[':help perl-patterns'](http://vimdoc.sourceforge.net/htmldoc/pattern.html#perl-patterns)獲取差異列表。你在用什麼來做搜索? – intuited 2011-04-15 09:58:29

+0

@BoltClock兩者兼得。最終我會使用perl,但我發現在vim中使用正則表達式更快。 – tog22 2011-04-15 11:21:22

回答

1

我把你的示例文本到一個Vim緩衝區,然後執行命令

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

結果僅僅是XML的第一個塊。我認爲這是你想要的?

請注意,我逃過了正則表達式中的/。除此之外,它與您的問題中給出的是相同的。

還要注意的是等效的VIM RE會(測試工作):

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

爲Perl和VIM的RE之間的差異破敗見:help perl-patterns

另外請注意parsing heirarchical markup with regexps has been known to reawaken ancient demons

+0

謝謝。對於什麼是值得的,你的vim RE不起作用 - 在vim中測試的時候能夠使用它我會很高興,但是perl RE是我真正需要的。 – tog22 2011-04-15 12:41:43

+0

...雖然你可以解釋爲什麼當我切換到負向前視圖時,以下功能無法按預期工作(僅捕獲文件中的第二個元素)。我有一種感覺,它與第一個的貪婪有關。*但是當我切換這個時。*?我找到了一個操作員。有沒有一種方法可以捕獲不包含'Story'的元素,還是使用regexps以外的工具更好? /\_.*\(story\)\@/ – tog22 2011-04-15 15:13:42

+0

@ tog22:我剛剛測試了vim RE,發現它可以同時適用於兩者['/'](http://vimdoc.sourceforge.net/htmldoc/pattern.html#/)和['matchstr()'](http://vimdoc.sourceforge.net/htmldoc/eval.html#matchstr ())。請注意,在vim中,你不需要(也不能)用'/'字符來包圍RE;我只是讓它們與perl-ish版本類似。我把它們拿出來了。 – intuited 2011-04-15 17:13:07

1

您的正則表達式中的第一個.*仍然是貪婪的。第二個之後你只添加了?

+4

但是,在這種情況下,前瞻將涵蓋'(?=故事)' – Seth 2011-04-15 10:05:03

+0

謝謝,但正如塞思指出,這裏沒有必要。 – tog22 2011-04-15 11:38:46