Ali
Ali

Reputation: 267049

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://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

Answers (6)

jayzantel
jayzantel

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

d7samurai
d7samurai

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

Oliver O&#39;Neill
Oliver O&#39;Neill

Reputation: 1254

<?

$dom = new DomDocument();
$dom->loadHTML($html);
$urls = $dom->getElementsByTagName('a');

Upvotes: 8

Sergi
Sergi

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

RolandasR
RolandasR

Reputation: 3047

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

Upvotes: 2

Diablo
Diablo

Reputation: 3418

Try something like this:

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

Upvotes: 2

Related Questions