繁体   English   中英

php preg_match_all反向引用

[英]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=&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。 但没有。

任何解决方案

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM