2013-08-23 77 views
0

我有一個file喜歡的東西perl的非貪婪正則表達式匹配的情況下過多

<post href="http://example.com/" description="Example website" tag="more text"/> 

我想要得到的是Example website。這樣做的:

cat file | perl -pe 's/.*description=".*?"//' 

按預期工作,我也得到tag="more text"/>,但是當試圖:

cat file | perl -pe 's/.*description="(.*)?"/\1/' 

我得到Example website" tag="more text/>,而我期待得到Example website。所以看起來有些東西的捕捉和反向引用不能按預期工作,儘管我想我可能會理解爲什麼,但我不知道如何解決它。

我總是可以做:

cat file | perl -pe 's/.*description="//;s/".*//' 

,但我真的想了解如何使用正則表達式解決的,而不是做兩個換人它。

+0

**不要使用正則表達式來解析HTML。使用合適的HTML解析模塊**您無法可靠地使用正則表達式解析HTML,並且您將面臨悲傷和挫折。只要HTML從你的期望改變,你的代碼就會被破壞。請參閱http://htmlparsing.com/perl以獲取如何使用已經編寫,測試和調試的Perl模塊正確解析HTML的示例。 –

+0

我知道我不應該試圖用正則表達式來解析HTML,但是這是從API調用中獲得的XML代碼,所以它不會偏離,因爲它已經只包含我感興趣的內容。如果API響應會發生變化,所以我的代碼必須適應,但是在這種情況下不會有任何不可預見的情況使正則表達式「危險」。 – user137369

回答

1

您不使用非貪婪,你有集團的結束括號之後的可選捕獲組的問號內貪婪是:

變化:

description="(.*)?" 

到:

description="(.*?)" 

你應該有你的預期結果。

+0

我認爲(並嘗試過),並且它不工作,我現在意識到爲什麼,我忘了放置尾隨'。*',所以它應該是'cat file | perl -pe's /.* description =「(。*?)」。*/\ 1 /''。我仍然會接受答案,謝謝。 – user137369

+0

如果您希望捕獲組僅包含說明值,則我的答案中的更改仍然是必需的。 – smerny

+0

是的,我知道,它現在按預期工作。謝謝。 – user137369

1

?元字符在正則表達式中有兩個含義。

當它跟隨一個像*+這樣的字符時,它允許一個表達式匹配不定次數,它就是「非貪婪」修飾符。

.*? 
a+? 
(foo){3,}?    # actually, I'm not sure about this one 

它 在其他情況下,它的意思是「匹配0或1次」

abc?d     # matches "abcd" or "abd" 

通過將?捕獲組外,你已經把它改成第二個意義。把它放在捕獲組中,就像@smerny所說的那樣。

(.*?)