繁体   English   中英

PHP Regex 使用捕获组匹配 HTML 代码

[英]PHP Regex to match HTML code using capturing group

我一直试图在 PHP 中编写一个正则表达式,该表达式使用捕获组匹配 A HREF 标签。

我当前的代码如下所示:

 $content = preg_replace_callback( '/<a[^>]*href=["|\\']([^"|\\']*)["|\\'][^>]*>([^<]*)<\\/a>/i', function($m) { ...

该代码非常适合这样的事情:

 <a href="/go/bla" rel="sponsored noopener" target="_blank">Test link</a>

但是我有一些看起来像这样的 URL - 注意嵌套的<span></span>

 <a href="/go/bla" rel="sponsored noopener" target="_blank"><span>Test link</span></a>

我的第二个捕获组匹配 ^< 这就是不匹配的原因。 我试图更改组以匹配任何 BUT 。 由于我缺乏正则表达式经验,这就是我失败的地方:)

任何正则表达式专家都可以指出我正确的方向吗?

这对于您的示例来说应该足够了

<a[^>]*href=["|\']([^"|\']*)["|\'][^>]*>(?:<[^>]+>)?([^<]*)(?:<[^>]+>)?<\/a>

添加(?:<[^>]+>)? 如果存在,将匹配额外的标签。

在此处查看此操作

当前的正则表达式应该可以帮助您:

<a[^>]*href=["|\']([^"|\']*)["|\'][^>]*>(?:<[^>]+>)*([^<]*)(?:</[^>]+>)*<\/a>

这将匹配您的示例以及此示例:

<a href="/go/bla" rel="sponsored noopener" target="_blank"><span><h1>Test link</h1></span></a>

然而这又如何呢?

<a href="/go/bla" rel="sponsored noopener" target="_blank"><span><h1>Test <span>link</span></h1></span></a>

不! 这断了。 现在我们必须回过头来考虑标签内的标签,这些标签外的文本仍然匹配,我们必须将其分解更多。 在这个阶段,最好只是简单地获取所有a标签的列表,然后执行一些替换以在事后提取您需要的数据。

$matches = preg_match_callback('/<a[^>]*?href=(.*?")[^>]*?>(.*?)</a>/i', function($m) {
  ... more regexes
}

最好考虑使用一个库,该库允许您将 html 内容作为对象加载(很像浏览器)并使用 xpath 之类的东西查询您的结果。

在 PHP 中,您可以使用 DOM 和 XPath 来加载 html。 下面是一个例子。

$doc = new DOMDocument();
$html = <<<EOD
<html>
<body>
<a href="/go/bla" rel="sponsored noopener" target="_blank">Test link</a>
<a href="/go/bla" rel="sponsored noopener" target="_blank"><span>Test link</span></a>
<a href="/go/bla" rel="sponsored noopener" target="_blank"><span><h1>Test <span>link</span></h1></span></a>
</body>
</html>
EOD;

$doc->loadHTML($html);
$xpath = new DOMXpath($doc);
$query = $xpath->query('//a');

if (!is_null($query)) {
    foreach ($query as $q) {
        print $q->getAttribute('href') . ' - ';
        print $q->nodeValue . "\n";
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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