抓取A元素的href属性

试图find页面上的链接。

我的正则expression式是:

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

但似乎失败了

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

如何改变我的正则expression式来处理不是首先放在标签中的href?

HTML的可靠正则expression式很难 。 这里是如何用DOM做到这一点:

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

上面的代码将find并输出$htmlstring中所有A元素的“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 } 

另请参阅:

  • parsingHTML的最佳方法
  • DOM中的DOMDocument

在旁注:我相信这是重复的,你可以在这里find答案

我同意戈登,你必须使用HTMLparsing器来parsingHTML。 但是,如果你真的想要一个正则expression式,你可以试试这个:

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

这与string开头的<a匹配,后跟任意数字的任何char(非贪婪) .*? 然后href=后面的链接包围"'

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

输出:

 array(3) { [0]=> string(37) "<a title="this" href="that">what?</a>" [1]=> string(1) """ [2]=> string(4) "that" } 

你想要查找的模式将是链接锚点模式,如(东西):

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

你为什么不匹配

 "<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" } } 

哪个工作。 我刚刚删除了第一个撷取大括号。

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

如果你真的需要使用正则expression式,那么看看这个工具,它可能会有所帮助: http : //regex.larsolavtorvik.com/

使用你的正则expression式,我修改了一下,以适应你的需要。

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

我个人build议你使用HTMLparsing器

编辑:testing

对于那些仍然没有使用SimpleXML来获得解决scheme的人来说非常简单快捷

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

它为我工作

快速testing: <a\s+[^>]*href=(\"\'??)([^\1]+)(?:\1)>(.*)<\/a>诀窍,第一场比赛是“or”,第二场是“href”值“that”,第三场是“what?”。

我之所以离开“/”的第一个匹配,是因为你可以用它来反向引用它,因为它是一样的。

http://www.rubular.com/r/jsKyK2b6do上查看活动示例;

preg_match_all(“/(]>)(。?)(</ a)/”,$ contents,$ impmatches,PREG_SET_ORDER);

它被testing,并从任何html代码中获取所有标签。