Reputation: 267049
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://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.
Upvotes: 6
Views: 19216
Reputation: 91
<?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.
Upvotes: 5
Reputation: 3216
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
Upvotes: 0
Reputation: 1254
<?
$dom = new DomDocument();
$dom->loadHTML($html);
$urls = $dom->getElementsByTagName('a');
Upvotes: 8
Reputation: 2892
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';
}
?>
Upvotes: 5
Reputation: 3418
Try something like this:
//not tested
$regex_pattern = "/<a href=\"(.*)\">(.*)<\/a>/";
Upvotes: 2