代码之家  ›  专栏  ›  技术社区  ›  TrooPhalce

如何使用PHP preg_match_all来区分由内部HTML元素的属性标识的锚元素?

  •  1
  • TrooPhalce  · 技术社区  · 10 年前

    我有一组HTML锚定元素,其中包含图像元素。对于每个集合,使用PHP-CLI,我希望提取URL并根据其类型对其进行分类。锚点的类型只能由其子图像元素的属性确定。如果每套只有一种类型,那就很容易了。我的问题是当一种类型的两个锚元素被一个或多个其他类型分隔开时。我的非贪婪括号化子模式似乎变得贪婪,并扩展到查找第二个相关的子属性。在我的测试脚本中,我试图从其他类型中提取“Userlink”URL。使用简单的模式,如:

    #<a href="(.*?)" custattr="value1"><img alt="Userlink"#
    

    在以下集合中:

    <li><a href="http://www.userlink1.com/my/page.html" custattr="value1"><img alt="Userlink" class="common_link_class" height="123" src="pic0.png" width="123" style="width: 123px;"></a></li><li><a href="http://www.socnet1.com/username1" custattr="value1"><img alt="Socnet1" class="common_link_class" height="123" src="pic1.png" width="123" style="width: 123px;"></a></li><li><a href="http://www.socnet2.com/username1" custattr="value1"><img alt="Socnet2" class="common_link_class" height="123" src="pic2.png" width="123" style="width: 123px;"></a></li><li><a href="mailto:useralias1@unlikely.zyx321.usermail.net" custattr="value1"><img alt="Usermail" class="common_link_class" height="123" src="pic3.png" width="123" style="width: 123px;"></a></li><li><a href="http://www.userlink2.com/my/page.html" custattr="value1"><img alt="Userlink" class="common_link_class" height="123" src="pic4.png" width="123" style="width: 123px;"></a></li>
    

    (抱歉,但实际的html就在这样的一行上)

    我的子模式从第一个“用户链接”URL的开头到最后一个URL的结尾进行捕获。

    我已经尝试了许多不同的外观,但我不确定是否应该在这里列出它们。到目前为止,他们要么根本没有返回匹配项,要么与上述相同。

    这是我的测试脚本(在Bash shell中运行):

    #!/usr/bin/php
    <?
        $lines = 0;
        $input = "";
        $matches = array();
    
        while ($line = fgets(STDIN)){
            $input .= $line;
            $lines++;
        }
        fwrite(STDERR, "Processing $lines\n");
    
        $pcre = '#<a href="(.*?)" custattr="value1"><img alt="Userlink"#';
    
        if (preg_match_all($pcre,$input,$matches)){
            fwrite(STDERR, "\$matches has " . count($matches) . " elements\n");
            foreach ($matches[1] as $match){
                fwrite(STDOUT, $match . "\n");
            }
        }
    ?>
    

    在上面的示例中,PHP的preg_match_all()的PCRE模式将返回两个“Userlink”URL?

    2 回复  |  直到 10 年前
        1
  •  0
  •   Casimir et Hippolyte    10 年前

    我冒昧地更改了您的变量名称:

    $pattern = '~<a href="([^"]++)" custattr="value1"><img alt="Userlink"~';
    
    if ($nb = preg_match_all($pattern, $input, $matches)) {
        fwrite(STDERR, "\$matches has " . $nb . " elements\n");
        fwrite(STDOUT, implode("\n", $match) . "\n");
    }
    

    注意 预匹配_全部 函数返回匹配数。

        2
  •  0
  •   Kamehameha    10 年前

    这个正则表达式应该可以工作-

    <a href="([^"]*?)"[^>]*\><img alt="Userlink"
    

    你可以看到它是如何工作的 here .

    测试它-

    $pcre = '/<a href="([^"]*?)"[^>]*\><img alt="Userlink"/';
    if (preg_match_all($pcre,$input,$matches)){
        var_dump($matches);
        //$matches[1] will be the array containing the urls.
    }
    /*
        OUTPUT- 
        array
          0 => 
            array
              0 => string '<a href="http://www.userlink1.com/my/page.html" custattr="value1"><img alt="Userlink"' (length=85)
              1 => string '<a href="http://www.userlink2.com/my/page.html" custattr="value1"><img alt="Userlink"' (length=85)
          1 => 
            array
              0 => string 'http://www.userlink1.com/my/page.html' (length=37)
              1 => string 'http://www.userlink2.com/my/page.html' (length=37)
    */