抓取A元素的href属性

时间:2010-09-29 10:18:15

标签: php html dom

尝试在网页上找到链接。

我的正则表达式是:

/<a\s[^>]*href=(\"\'??)([^\"\' >]*?)[^>]*>(.*)<\/a>/

但似乎在

失败了
<a title="this" href="that">what?</a>

如何更改正则表达式以处理未首先放在标签中的href?

10 个答案:

答案 0 :(得分:204)

Reliable Regex for HTML are difficult。以下是DOM

的使用方法
$dom = new DOMDocument;
$dom->loadHTML($html);
foreach ($dom->getElementsByTagName('a') as $node) {
    echo $dom->saveHtml($node), PHP_EOL;
}

以上内容将查找并输出A字符串中所有$html个元素的"outerHTML"

获取节点的所有文本值,请执行

echo $node->nodeValue; 

检查,如果存在href属性,则可以执行

echo $node->hasAttribute( 'href' );

获取您要执行的href属性

echo $node->getAttribute( 'href' );

更改您要执行的href属性

$node->setAttribute('href', 'something else');

删除您要执行的href属性

$node->removeAttribute('href'); 

您还可以直接使用XPath

查询href属性
$dom = new DOMDocument;
$dom->loadHTML($html);
$xpath = new DOMXPath($dom);
$nodes = $xpath->query('//a/@href');
foreach($nodes as $href) {
    echo $href->nodeValue;                       // echo current attribute value
    $href->nodeValue = 'new value';              // set new attribute value
    $href->parentNode->removeAttribute('href');  // remove attribute
}

另见:

旁注:我相信这是重复的,你可以find the answer somewhere in here

答案 1 :(得分:17)

我同意Gordon,你必须使用HTML解析器来解析HTML。但如果你真的想要一个正则表达式,你可以尝试这个:

/^<a.*?href=(["\'])(.*?)\1.*$/

这匹配字符串开头的<a,后跟任意数量的任何字符(非贪婪).*?然后href=,后跟{{1}所包围的链接}或"

'

输出:

$str = '<a title="this" href="that">what?</a>';
preg_match('/^<a.*?href=(["\'])(.*?)\1.*$/', $str, $m);
var_dump($m);

答案 2 :(得分:5)

您要查找的模式将是链接锚点模式,如(某事):

$regex_pattern = "/<a href=\"(.*)\">(.*)<\/a>/";

答案 3 :(得分:3)

为什么你不匹配

"<a.*?href\s*=\s*['"](.*?)['"]"

<?php

$str = '<a title="this" href="that">what?</a>';

$res = array();

preg_match_all("/<a.*?href\s*=\s*['\"](.*?)['\"]/", $str, $res);

var_dump($res);

?>

然后

$ php test.php
array(2) {
  [0]=>
  array(1) {
    [0]=>
    string(27) "<a title="this" href="that""
  }
  [1]=>
  array(1) {
    [0]=>
    string(4) "that"
  }
}

哪个有效。我刚刚删除了第一个捕获括号。

答案 4 :(得分:3)

对于那些仍然没有使用SimpleXML轻松快速地获得解决方案的人

$a = new SimpleXMLElement('<a href="www.something.com">Click here</a>');
echo $a['href']; // will echo www.something.com

它为我工作

答案 5 :(得分:2)

我不确定你在这里要做什么,但如果你想验证链接,那么看看PHP的filter_var()

如果您确实需要使用正则表达式,请查看此工具,它可能有所帮助: http://regex.larsolavtorvik.com/

答案 6 :(得分:2)

使用你的正则表达式,我修改了一下以满足你的需要。

<a.*?href=("|')(.*?)("|').*?>(.*)<\/a>

我个人建议您使用HTML Parser

编辑:经过测试

答案 7 :(得分:1)

快速测试:<a\s+[^>]*href=(\"\'??)([^\1]+)(?:\1)>(.*)<\/a>似乎可以解决问题,第一场比赛是“或”,第二场是'href'值'那',第三场是'什么?'。

我离开“/”的第一个匹配的原因是你可以用它来后面反馈它来关闭“/”所以它是一样的。

请参阅http://www.rubular.com/r/jsKyK2b6do

上的实时示例

答案 8 :(得分:0)

preg_match_all(“/(] &gt;)(。?)(&lt; / a)/”,$ contents,$ impmatches,PREG_SET_ORDER);

经过测试,它可以从任何HTML代码中获取所有标记。

答案 9 :(得分:0)

以下内容对我有用,并同时返回锚标记的hrefvalue

preg_match_all("'\<a.*?href=\"(.*?)\".*?\>(.*?)\<\/a\>'si", $html, $match);
if($match) {
    foreach($match[0] as $k => $e) {
        $urls[] = array(
            'anchor'    =>  $e,
            'href'      =>  $match[1][$k],
            'value'     =>  $match[2][$k]
        );
    }
}

名为$urls的多维数组现在包含易于使用的关联子数组。