[英]php preg_match_all backreference
對於以下輸入字符串,模式和:
$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="credit">[\s]+?Dir:([,\s]+?<a[\s]+?href="\/name\/nm\d{7}\/">([\/\(\)-:@!%*#=_|?$&;.\w\s]+?)<\/a>)+/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 ) )
你可以看到Array [2]給了Aditya Parikh,我也希望收到Vinton Heuck和Ciro Nieli。 但沒有。
任何解決方案
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表示它是第一個反向引用(我們只有1個括號)。 其中的0-2索引對應於每個匹配。 換句話說,表達式運行了3次,直到完成。
我希望這有幫助。
您應該考慮使用DOM解析器。 例如, 這一個 。 正則表達式無法正確解析HTML。
但是,這就是為什么您的方法不能按預期工作的原因:
您對所有3個名稱使用相同的捕獲組。 但是一個捕獲組只有一個數字,所以你總是會得到最后捕獲的東西(最右邊的名字)。 但即使您只匹配一個名稱(任意遠離span
標記),您也會遇到另一個問題:
匹配不能重疊。 由於您想要的所有三個匹配項至少包含class="credit"> Dir:
以及一些更常見的文本,因此您無法獲得所有這些匹配項。 你可以用一個lookbehind斷言來解決這個問題(因為它不是匹配的一部分),但不幸的是PHP不允許可變長度的lookbehinds(這是必需的)。 有一些解決方法可以解決這個問題,但在一天結束時,您最好使用DOM解析器。
以下是使用我上面鏈接的解析器的基本示例:
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);
導致:
Array
(
[0] => Vinton Heuck
[1] => Ciro Nieli
[2] => Aditya Parikh
)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.