如何使用正则表达式解析此HTML?

Pet*_*Lur 1 php regex

我正在尝试编写正则表达式来从HTML源中提取URL列表hrefanchor文本.该anchor文本可以是任意值.

HTML部分如下:

<div class="links"><a rel="nofollow" target="_blank" href="http://url1.com" class="get-all">URL1</a><a rel="nofollow" target="_blank" href="http://url2.com" class="get-all">This is Url-2</a><a rel="nofollow" target="_blank" href="http://url3.com" class="get-all">This is Url-3</a><a rel="nofollow" target="_blank" href="http://url4.com" class="get-all">Sweet URL 4</a></div>
Run Code Online (Sandbox Code Playgroud)

我尝试了以下正则表达式,但由于它在</a>标记之前抓取所有内容并失败,因此无法正常工作.

preg_match_('/<a rel="nofollow" target="_blank" href="(.*)" class="see-all">(.*)<\/a>/', $source , $website_array);
Run Code Online (Sandbox Code Playgroud)

提取我所需数据的正则表达式是什么?

Ja͢*_*͢ck 6

如果你必须知道,表达式是贪婪的,所以它可能匹配第一个锚的开始和最后一个的结束; 该/U修改将解决这个问题:

preg_match('/<a rel="nofollow" target="_blank" href="(.*)" class="see-all">(.*)<\/a>/U', $source , $website_array);
Run Code Online (Sandbox Code Playgroud)

请注意,pcre.backtrack_limit适用于ungreedy模式.

使用预见集可能会提供更好的性能:

preg_match('/<a rel="nofollow" target="_blank" href="([^"]*)" class="see-all">([^<]*)<\/a>/', $source , $website_array);
Run Code Online (Sandbox Code Playgroud)

这将导致锚本身内的标签出现问题.

有了上述限制,我会认真考虑使用HTML解析器:

$d = new DOMDocument;
$d->loadHTML($source);
$xp = new DOMXPath($d);
foreach ($xp->query('//a[@class="see-all"][@rel="nofollow"][@target="_blank"]') as $anchor) {
    $href = $anchor->getAttribute('href');
    $text = $anchor->nodeValue;
}
Run Code Online (Sandbox Code Playgroud)

演示

这将很乐意以不同的顺序处理属性,并使您能够进一步查询内部等.