2012-10-22 54 views
0

以下輸入字符串,圖案和:PHP preg_match_all反向引用

$str1 = 'span class="outline">Iron Man butts heads with Nick Fury and Shield after HYDRA attacks a meeting of the United Nations.</span> 
<span class="credit"> 
    Dir: <a href="/name/nm0381817/">Vinton Heuck</a>, <a href="/name/nm1367649/">Ciro Nieli</a>, <a href="/name/nm1367649/">Aditya Parikh</a>' 

$pattern='/class=&quot;credit&quot;&gt;[\s]+?Dir:([,\s]+?&lt;a[\s]+?href=&quot;\/name\/nm\d{7}\/&quot;&gt;([\/\(\)-:@!%*#=_|?$&;.\w\s]+?)&lt;\/a&gt;)+/um'; 

preg_match_all($pattern,$str1,$dir); 

輸出爲的print_r如下:

Array ([0] => Array ([0] => class="credit"> Dir: <a href="/name/nm0381817/">Vinton Heuck</a>, <a href="/name/nm1367649/">Ciro Nieli</a>, <a href="/name/nm1367649/">Aditya Parikh</a>) [1] => Array ([0] => , <a href="/name/nm1367649/">Aditya Parikh</a>) [2] => Array ([0] => Aditya Parikh)) 

正如可以看到數組[2]給出阿迪蒂亞Parikh的,我希望能夠迎來Vinton Heuck和Ciro Nieli。但沒有。

任何解決方案?

+0

這裏有關於使用HTML的正則表達式的其他幾個問題:

require "simple_html_dom.php"; $html = str_get_html($str1); $names = array(); foreach($html->find('span[class=credit] a') as $link) $names[] = $link->innertext; print_r($names); 

,導致。閱讀其中的一些內容,看看爲什麼不推薦。 –

回答

1

preg_match_all返回的匹配數組背後的邏輯並不那麼明顯。

首先,不要使用正則表達式來解析html。這樣說:

你得到的結果是形式$array[paren_num][match_num]

一個基本的例子: abc撞上了正則表達式/(.)/將返回以下比賽數組:

Array 
(
    [0] => Array 
     (
      [0] => a 
      [1] => b 
      [2] => c 
     ) 

    [1] => Array 
     (
      [0] => a 
      [1] => b 
      [2] => c 
     ) 

) 

0包含的所有消耗的數據的索引。索引1意味着它是第一個反向引用(我們只有一個括號)。其中的0-2索引對應於每個匹配。換句話說,表達是跑了3次,直到完成。

我希望這會有所幫助。

1

你應該真的考慮使用DOM解析器。例如,this oneRegular expressions just cannot properly parse HTML.

然而,這是爲什麼按照預期的方式不起作用:

您使用相同的捕獲組的所有3名。但是一個捕獲組只有一個數字,所以你總是會得到最後被捕獲的東西(最右邊的名字)。但即使你只是匹配一個名字(任意遠到span標籤),你會得到一個不同的問題:

匹配不能重疊。因爲你想要的所有三場比賽至少包含class="credit"> Dir:和一些更常見的文字,所以你不能得到所有這些。你可以用lookbehind斷言來解決這個問題(因爲它不是匹配的一部分),但不幸的是PHP不允許可變長度lookbehinds(這將是必需的)。有解決方法可以解決這個問題,但在一天結束時,您最好使用DOM解析器。

下面是一個使用我上面鏈接解析器只是一個基本的例子:

Array 
(
    [0] => Vinton Heuck 
    [1] => Ciro Nieli 
    [2] => Aditya Parikh 
)