Regexp for extracting all links and anchor texts from HTML
I'd like one or more regexes that can:
1) Take the html of a large page.
2) Find the urls contained in all links, for example:
<a href="http://example1.com">Test 1</a>
<a class="foo" id="bar" href="http开发者_Go百科://example2.com">Test 2</a>
<a onclick="foo();" id="bar" href="http://example3.com">Test 3</a>
And so on, it should extract the url contained in the 'href'
attribute regardless of what comes before or after the href
3) Extract the anchor text of all links, for example in the above examples, it should return 'http://example1.com' and the anchor text 'Test 1', then 'http://example2.com' and 'Test 2', and so on.
<?
$dom = new DomDocument();
$dom->loadHTML($html);
$urls = $dom->getElementsByTagName('a');
You need to take a look at look ahead and look behind.
<?php
$string = '<a href="http://example1.com">Test 1</a>
<a class="foo" id="bar" href="http://example2.com">Test 2</a>
<a onclick="foo();" id="bar" href="http://example3.com">Test 3</a>';
if(preg_match_all("|<a.*(?=href=\"([^\"]*)\")[^>]*>([^<]*)</a>|i", $string, $matches))
{
/*** if we find the word white, not followed by house ***/
echo 'Found a match';
print_r($matches);
}
else
{
/*** if no match is found ***/
echo 'No match found';
}
?>
<?php
$regexp = "<a\s[^>]*href=(\"??)([^\" >]*?)\\1[^>]*>(.*)<\/a>";
if(preg_match_all("/$regexp/siU", $html, $matches, PREG_SET_ORDER))
{ foreach($matches as $match)
{// $match[2] = link address
// $match[3] = link text}
}
?>
This will extract both the link and the anchor text.
Try something like this:
//not tested
$regex_pattern = "/<a href=\"(.*)\">(.*)<\/a>/";
/<a[^>]+href\s*=\s*["']([^"']+)["'][^>]*>(.*?)<\/a>/mis
As far as using RegEx to extract links from HTML goes, this one is pretty damn robust:
\b(((src|href|action|url) *(=|:) *(?<mh>"|'|))(?<url>[\w ~$!*'/.?=#&@:%+,();\-\[\]]+)\k<mh>|url *\( *(?<mc>"|'|)(?<url>[\w ~$!*'/.?=#&@:%+,();\-\[\]]+)\k<mc>\))
Here's one that extracts all 'plain' text (i.e. content outside tags) from HTML documents:
(<(?<tag>script|style)[\s\S]*?</\k<tag>>)|<!--[\s\S]*?-->|<[\s\S]*?>|(?<text>[^<>]*)
Test them both here: http://www.martinwardener.com/regex
精彩评论