2010-05-21 39 views
22

我想解析一個單一的字符串,並從相同的正則表達式條件獲取相同的字符串中的多個數據塊。我解析一個HTML文件,讓是靜態的(爲未公開的原因,我不能使用HTML解析器來完成這項工作。)我有,看起來像一個表達式:如何從同一個Perl正則表達式捕獲多個匹配?

$string =~ /\<img\ssrc\="(.*)"/; 

,我想獲得$ 1的價值。然而,在一個字符串中,有很多這樣的img標籤,所以我需要返回一個數組(@ 1?)這可能嗎?

+0

在這些情況下,我添加更多的上下文到我的正則表達式來到我想要的特定圖像標籤。也就是說,當我不喜歡使用HTML解析器進行正確的操作時,比如HTML :: SimpleLinkExtor,它會爲您抽取所有img src值。 – 2010-05-22 15:42:56

回答

19

吉姆的回答,請使用/ g的改性劑(在列表上下文或循環)。

但是要小心貪心,你不想要.*超過必要的匹配(並且不要逃避< =,它們不是特別的)。

while($string =~ /<img\s+src="(.*?)"/g) { 
    ... 
} 
+0

真棒,是的,我有一個貪婪的問題,那?修復。說,你會碰巧知道需要在正則表達式中逃脫的字符列表嗎?我基本上逃避幾乎所有的事情,因爲我不知道更好:P – 2010-05-21 18:55:23

+0

一般而言,您必須轉義元字符和量詞。在Perl中你有:'元字符:。 $^| ()[] \量詞:* +? {}' 但是有一些複雜性 - 特別是在一個字符類內部[]事情發生了變化。 – leonbloy 2010-05-21 19:12:57

+1

...但解決貪婪問題的更好方法是使用'「([^」] *)「'。在許多正則表達式引擎中,這將更有效率,但更重要的是,它更清晰地聲明你的意圖是:你想匹配「後跟一些*非雙引號*字符,然後是另一個」,而不是兩個「字符,由儘可能短的*任何字符序列*分隔。 – 2010-05-22 16:31:47

2

使用左邊/ g的改性劑和列表上下文,如

@result = $string =~ /\<img\ssrc\="(.*)"/g; 
+0

但我沒有一個字符串數組,只有一個。我試圖從單個字符串中的多個img標記中獲取各個源,並將其作爲數組返回。我試過這個,但它沒有返回任何東西。 – 2010-05-21 18:44:21

+0

羅伯特的答案給出了這種方法的正確語法 – leonbloy 2010-05-21 19:19:21

+0

你認爲綁定操作符在做什麼? :) – 2010-05-22 15:41:06

5

你只需要全局修改/ G在比賽結束。然後遍歷 ,直到沒有匹配剩餘

my @matches; 
while ($string =~ /\<img\ssrc\="(.*)"/g) { 
     push(@matches, $1); 
} 
7
@list = ($string =~ m/\<img\ssrc\="(.*)"/g); 

改性劑中的字符串中的所有字符的字符串匹配。列表上下文返回所有匹配。請參閱perlop中的m //運算符。