Regex pour détecter un lien

Petit nouveau ! | 7 Messages

26 janv. 2013, 13:26

Bonjour,

Je cherche à extraite le titre d'un lien à partir de son code HTML. Svp, pourquoi ce code ne fonctionne pas ?

Code : Tout sélectionner

preg_match_all('#<a href="([^ ]+)">([^(</a>)]+)</a>#', $file_contents, $matches);

Eléphant du PHP | 120 Messages

26 janv. 2013, 14:36

Les expressions régulières ne sont pas faites pour ce genre de choses. Je te conseille d'utiliser un parser DOM à la place :
http://be1.php.net/manual/fr/domdocument.loadhtml.php

ViPHP
AB
ViPHP | 5818 Messages

29 janv. 2013, 02:08

Bonjour,

Je cherche à extraite le titre d'un lien à partir de son code HTML. Svp, pourquoi ce code ne fonctionne pas ?

Code : Tout sélectionner

preg_match_all('#<a href="([^ ]+)">([^(</a>)]+)</a>#', $file_contents, $matches);
j'ai pas regardé en détail le contenu de ton masque mais pour qu'un regex puisse explorer au delà des retours lignes il faut ajouter l'option "s".

Ci-dessous des solutions avec DomDocument et preg_match_all
<?php
$page_cible = 'http://forum.phpfrance.com/php-debutant/regex-pour-detecter-lien-t266971.html';


// DomDocument
$tab = array();

$dom = new DOMDocument;

if(@$dom->loadHTMLFile($page_cible))
	{
		// Sélectionne toutes les balises "a"
		$domliste = $dom->getElementsByTagName('a');
		
		foreach($domliste as $a) 
		{
			//$a->getAttribute('href') contenu du href
			$attribut_href = $a->getAttribute('href');
			//$a->nodeValue contenu du libellé entre <a> et </a>
			if (isset($attribut_href)) $tab[$attribut_href] = $a->nodeValue;
		}
	}
	else
	{
		echo 'le document '.$page_cible. ' n\'a pas pu être chargé';
	}

echo '<pre>';
print_r($tab);
echo '</pre>';
echo 'total = '.count($tab);


// variante avec DomDocument et une requête xpath 
$store = array();

$dom = new DOMDocument;

if(@$dom->loadHTMLFile($page_cible))
	{
		$xpath = new DOMXPath($dom);
		
		// Sélectionne toutes les balises "a" qui possèdent un attribut href
    	        $items = $xpath->query('//a[@href]');
 
    	        foreach($items as $a)
    	        {
			$store[$a->getAttribute('href')] = $a->nodeValue;
		}
	}
	else
	{
		echo 'le document '.$page_cible. ' n\'a pas pu être chargé';
	}
	
echo '<pre>';
print_r($store);
echo '</pre>';
echo 'total = '.count($store);



//preg_match
$result = array();

$str = file_get_contents($page_cible);

preg_match_all('#.*<a.*href.*"(.*)".*>(.*)</a>.*#isU',$str,$match);
if (isset($match[1])) 
{
	foreach($match[1] as $key => $href)
	{
		$result[$href] = isset($match[2][$key])? $match[2][$key] : '';
	}
}
echo '<pre>';
print_r($result);
echo '</pre>';
echo 'total = '.count($result);

?>

Mais bon il est vrai que domdocument est plus adapté qu'un preg_match (et moins gourmand en ressources).
Preg_match récupère même les liens mis entre commentaires et c'est moins facile qu'avec domdocument pour ne récupérer uniquement que les libellés.