0

对于以下输入字符串、模式和:

$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 ) )

正如你所看到的,Array[2] 给了 Aditya Parikh,我也希望能收到 Vinton Heuck 和 Ciro Nieli。但没有。

有什么解决办法??

4

2 回答 2

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 次,直到完成。

我希望这有帮助。

于 2012-10-22T08:43:40.537 回答
1

您真的应该考虑使用 DOM 解析器。比如这个正则表达式无法正确解析 HTML。

但是,这就是您的方法无法按预期工作的原因:

您对所有 3 个名称使用相同的捕获组。但是一个捕获组只有一个数字,所以你总是会得到最后一个被捕获的东西(最右边的名字)。但即使你只匹配一个名字(在span标签中任意远),你也会遇到不同的问题:

匹配不能重叠。由于您想要的所有三个匹配项都至少包含class="credit"> Dir:一些更常见的文本,因此您无法获得所有这些。您可以使用后向断言来解决此问题(因为它不是匹配的一部分),但不幸的是 PHP 不允许可变长度后向(这是必需的)。有一些解决方法可以解决这个问题,但归根结底,最好使用 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
)
于 2012-10-22T08:59:03.327 回答