Précédent   Forum des professionnels en informatique > PHP > Langage > Regex
Regex Forum d'entraide sur les expressions rationnelles PHP. Avant de poster -> FAQ regex, Cours de regex et Sources de regex
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 12/05/2011, 15h21   #1
Nouveau Membre du Club
 
Homme
Développeur informatique
Inscription : mai 2011
Messages : 12
Détails du profil
Informations personnelles :
Sexe : Homme

Informations professionnelles :
Activité : Développeur informatique
Secteur : High Tech - Multimédia et Internet

Informations forums :
Inscription : mai 2011
Messages : 12
Points : 27
Points : 27
Par défaut Capture de lien

Bonjour ,

Je bute sur une regex et je n'arrive pas à continuer mon boulot sans elle, alors après quelques recherches infructueuses je me permet de vous solliciter pour trouver mon bonheur :p.

En bref à partir du code HTML d'une page je souhaite obtenir un lien qui contient un mot clé et capturer différentes partie de ce lien, exemple (ici le mot clé sera "contact") :

Code :
<a href="presse/nous-contacter/"  >Nous contacter</a>
Ici j'aimerais tout d'abord trouver ce lien et capturer '<a href="' , 'presse/nous-contacter/' , et '" >Nous contacter</a>', jusque la pas de problème j'y parviens grâce à cette regex :
Code :
(<a [^>]*href=["']{1})([^"']*)(["']{1}[^>]*>[^<]*?contact[^<]*?</a>)
Je n'avais pas réfléchi à un cas qui pourrait se présenter, parfois le lien est de la forme
Code :
<a ...><strong>*contact*</strong></a>
et dans ce cas la... ma regex ne capture pas puisque j'utilisais [^<]* pour ne pas avoir plusieurs liens capturés en même temps.

Ce que je cherche à faire c'est capturer un lien peu importe ce qu'il y a comme balises (sauf </a> balise fermante du lien..) entre <a> et </a> , mais je n'y parviens pas si je vire les [^<]* de chaque coté de contact je me retrouve avec des matchs de plusieurs liens, et je ne sais pas comment faire pour dire "n'importe quel caractère tant qu'il n'y a pas cette chaine (</a>).

Un petit coup de main ne serait pas de refus
J'espère que je ne vous ai pas perdu en route, je ne suis pas très doué pour les explications...
Merci
CyPh3rZz est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 12/05/2011, 16h06   #2
Modérateur
 
Inscription : septembre 2010
Messages : 7 103
Détails du profil
Informations forums :
Inscription : septembre 2010
Messages : 7 103
Points : 8 466
Points : 8 466
pour parser du HTML c'est DOMDocument et grace a XPath tu pourras faire une recherche sur le mot désiré
__________________
http://blog.stealth35.com/
stealth35 est déconnecté   Envoyer un message privé Réponse avec citation 20
Vieux 12/05/2011, 16h27   #3
Nouveau Membre du Club
 
Homme
Développeur informatique
Inscription : mai 2011
Messages : 12
Détails du profil
Informations personnelles :
Sexe : Homme

Informations professionnelles :
Activité : Développeur informatique
Secteur : High Tech - Multimédia et Internet

Informations forums :
Inscription : mai 2011
Messages : 12
Points : 27
Points : 27
Re, merci de ta réponse,

Je suis au courant qu'il existe des library pour parser du HTML j'utilise simple_html_dom pour une autre partie de mon script.
Ici vu que mon critère de recherche est entre les balises et non un attribut des balises, cela reviendrait à parser tous les liens puis faire une recherche dans chacun d'eux... je ne sais pas si cela serait efficace niveau perf.

J'ai regardé un peu la doc XPath (que je ne connaissais pas au passage, merci) mais je ne vois pas trop comment cette lib pourrait m'aider... Il me semble que le problème soit le même on peut trier en fonction des attributs mais pas du contenu, si ?

Je me trompe peut-être, j'ai juste regardé vite fait XPath mais des exemples que j'ai vu aucun ne présente la possibilité de faire ce que je souhaite.

Je passerais par la méthode du parser + recherche individuelle si rien de mieux ne se présente en attendant si quelqu'un à une autre solution...
CyPh3rZz est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 12/05/2011, 16h29   #4
Modérateur
 
Inscription : septembre 2010
Messages : 7 103
Détails du profil
Informations forums :
Inscription : septembre 2010
Messages : 7 103
Points : 8 466
Points : 8 466
tu peux faire ça avec la fonctions contains de xpath :
http://support.microsoft.com/kb/304265
__________________
http://blog.stealth35.com/
stealth35 est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 12/05/2011, 16h33   #5
Nouveau Membre du Club
 
Homme
Développeur informatique
Inscription : mai 2011
Messages : 12
Détails du profil
Informations personnelles :
Sexe : Homme

Informations professionnelles :
Activité : Développeur informatique
Secteur : High Tech - Multimédia et Internet

Informations forums :
Inscription : mai 2011
Messages : 12
Points : 27
Points : 27
Hum.. ça parait bien, merci je met résolu si je réussi à l'implémenter
CyPh3rZz est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 13/05/2011, 09h41   #6
Nouveau Membre du Club
 
Homme
Développeur informatique
Inscription : mai 2011
Messages : 12
Détails du profil
Informations personnelles :
Sexe : Homme

Informations professionnelles :
Activité : Développeur informatique
Secteur : High Tech - Multimédia et Internet

Informations forums :
Inscription : mai 2011
Messages : 12
Points : 27
Points : 27
Encore moi, il doit y avoir un truc qui m’échappe...

J'ai fait ceci :
Code :
1
2
3
4
5
6
7
8
9
 
$doc = new DOMDocument();
@$doc->loadHTML($corps);
 
$xpath = new DOMXPath($doc);
$elements = $xpath->query("//a[contains(.,'contact')]");
while(list( , $node) = each($elements)) {
	echo $node->asXML();
}
Mais ça ne me renvoie rien... pourtant j'ai vérifié à la main et il y a bien des liens qui contiennent "contact" : /

cf php.net

Edit :
En fait si je met un echo "test"; dans ma boucle ça n'affiche toujours rien donc je suppose que c'est ma requête xpath qui ne renvoie pas de résultat, y aurait-il une erreur de syntaxe ?
CyPh3rZz est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 13/05/2011, 10h19   #7
Modérateur
 
Inscription : septembre 2010
Messages : 7 103
Détails du profil
Informations forums :
Inscription : septembre 2010
Messages : 7 103
Points : 8 466
Points : 8 466
il faut toujours mettre le niveau d'erreur au maximum quand tu développes,
asXML c'est du SimpleXML pas du DOMDocument
__________________
http://blog.stealth35.com/
stealth35 est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 13/05/2011, 10h41   #8
Nouveau Membre du Club
 
Homme
Développeur informatique
Inscription : mai 2011
Messages : 12
Détails du profil
Informations personnelles :
Sexe : Homme

Informations professionnelles :
Activité : Développeur informatique
Secteur : High Tech - Multimédia et Internet

Informations forums :
Inscription : mai 2011
Messages : 12
Points : 27
Points : 27
Mon niveau d'erreur est à E_ALL | E_STRICT et j'ai mis le "@" devant le load parce que certaines pages que je scan sont tellement mal faites qu'elles génèrent des warning lors du chargement du genre :

Warning: DOMDocument::loadHTML() [domdocument.loadhtml]: error parsing attribute name in Entity, line: 29 in C:\wamp\www\getContact\lib.php on line 12

J'ai test saveHTML() mais nada...

Code :
1
2
3
4
5
6
7
 
$xpath = new DOMXPath($doc);
//$elements = $xpath->query("//a[contains(.,'contact')]");
$elements = $xpath->query('//a');
while(list( , $node) = each($elements)) {
     echo $node->saveHTML();
}
J'ai fait une requête plus simple avec juste les liens mais pas de résultats...
CyPh3rZz est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 13/05/2011, 10h56   #9
Modérateur
 
Inscription : septembre 2010
Messages : 7 103
Détails du profil
Informations forums :
Inscription : septembre 2010
Messages : 7 103
Points : 8 466
Points : 8 466
pour ne pas afficher les erreurs c'est libxml_use_internal_errors

saveHTML() ne marche que sur un DOMDocument, si tu veux voir le contenu du node c'est nodeValue

t'as boucle n'est pas bonne non plus, utilise un foreach sur $elements
__________________
http://blog.stealth35.com/
stealth35 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/05/2011, 11h10   #10
Nouveau Membre du Club
 
Homme
Développeur informatique
Inscription : mai 2011
Messages : 12
Détails du profil
Informations personnelles :
Sexe : Homme

Informations professionnelles :
Activité : Développeur informatique
Secteur : High Tech - Multimédia et Internet

Informations forums :
Inscription : mai 2011
Messages : 12
Points : 27
Points : 27
Code :
1
2
3
4
5
6
7
8
9
10
 
$doc = new DOMDocument();
@$doc->loadHTML($corps);
 
$xpath = new DOMXPath($doc);
//$elements = $xpath->query("//a[contains(.,'contact')]");
$elements = $xpath->query('/html/body/a');
foreach($elements as $element){
	echo $element->nodeValue."<br/>\n";
}
Ça match un truc mais euh... rien a voir avec ce que j'ai demandé il me choppe un lien en bas de page, et entre les balises de ce lien il y a du JS, enfin bref bizarre qu'il ne trouve pas les autres liens qui sont tout simple comme <a href="contact/">Contact</a> ...

Je sens que je vais passer sur une autre solution
Par contre pour nodeValue c'est pas tout à fait ce que je veux, je souhaite récupérer le code html pas le contenu de la balise.
CyPh3rZz est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 13/05/2011, 11h15   #11
Modérateur
 
Inscription : septembre 2010
Messages : 7 103
Détails du profil
Informations forums :
Inscription : septembre 2010
Messages : 7 103
Points : 8 466
Points : 8 466
je comprend pas ta mis 3 code et t'as fait 3 requêtes différentes... pourquoi ?
si tu veux récupérer le lien il faut faire un getAttribute avec href, ou directe le faire dans ta requete xpath ( @href)
__________________
http://blog.stealth35.com/
stealth35 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/05/2011, 11h20   #12
Nouveau Membre du Club
 
Homme
Développeur informatique
Inscription : mai 2011
Messages : 12
Détails du profil
Informations personnelles :
Sexe : Homme

Informations professionnelles :
Activité : Développeur informatique
Secteur : High Tech - Multimédia et Internet

Informations forums :
Inscription : mai 2011
Messages : 12
Points : 27
Points : 27
Oui désolé, c'est que j'ai fait quelques test et j'ai pas fait gaffe à ce que je copiais, en gros ce que je veux c'est trouver les liens qui contiennent "contact" entre leurs balises et récupérer l'adresse qu'ils pointent.
Ex :
Code :
<a href="pouet/">contact</a>
Il n'y a pas contact dans le href mais on s'en fou on veut juste que ce soit dans les balises donc on choppe "pouet/" comme adresse.

Pensant que le problème venait du contains j'avais test sur n'importe quel lien mais même résultat.

Sinon bah j'ai contourné le problème avec une autre méthode plus lente... :

Code :
1
2
3
4
5
6
7
8
9
 
$html = new simple_html_dom();
$html->load($corps);
$resultA=$html->find("a");
foreach($resultA as $current){
	if(preg_match("#>.*contact.*<#i",$current)){
	         echo htmlentities($current)."<br/>";
        }
}
mais la solution m’intéresse toujours
CyPh3rZz est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 13/05/2011, 11h28   #13
Modérateur
 
Inscription : septembre 2010
Messages : 7 103
Détails du profil
Informations forums :
Inscription : septembre 2010
Messages : 7 103
Points : 8 466
Points : 8 466
la requete xpath c'est : //a[contains(.,'contact')]/@href
__________________
http://blog.stealth35.com/
stealth35 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/05/2011, 11h35   #14
Nouveau Membre du Club
 
Homme
Développeur informatique
Inscription : mai 2011
Messages : 12
Détails du profil
Informations personnelles :
Sexe : Homme

Informations professionnelles :
Activité : Développeur informatique
Secteur : High Tech - Multimédia et Internet

Informations forums :
Inscription : mai 2011
Messages : 12
Points : 27
Points : 27
Code :
1
2
3
4
5
6
7
$doc = new DOMDocument();
@$doc->loadHTML($corps);		
$xpath = new DOMXPath($doc);
$elements = $xpath->query("//a[contains(.,'contact')]/@href");		
foreach($elements as $element){
	echo $element->nodeValue."<br/>\n";
}
Ne renvoie rien alors que :
Code :
1
2
3
4
5
6
7
8
9
 
$html = new simple_html_dom();
$html->load($corps);
$resultA=$html->find("a");
foreach($resultA as $current){
	if(preg_match("#>.*?contact.*?<#i",$current)){
		echo htmlentities($current)."<br/>";
	}
}
me renvoie un lien... le principe est le même mais pas le résultat
CyPh3rZz est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 13/05/2011, 11h39   #15
Modérateur
 
Inscription : septembre 2010
Messages : 7 103
Détails du profil
Informations forums :
Inscription : septembre 2010
Messages : 7 103
Points : 8 466
Points : 8 466
tu vérifies même pas les valeurs de retour, le @href te reverras un DOMAttr, y'a pas de nodeValue
__________________
http://blog.stealth35.com/
stealth35 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/05/2011, 11h49   #16
Nouveau Membre du Club
 
Homme
Développeur informatique
Inscription : mai 2011
Messages : 12
Détails du profil
Informations personnelles :
Sexe : Homme

Informations professionnelles :
Activité : Développeur informatique
Secteur : High Tech - Multimédia et Internet

Informations forums :
Inscription : mai 2011
Messages : 12
Points : 27
Points : 27
Code :
echo $element->value."<br/>\n";
? Nothing new
CyPh3rZz est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 13/05/2011, 17h30   #17
Modérateur
 
Inscription : septembre 2010
Messages : 7 103
Détails du profil
Informations forums :
Inscription : septembre 2010
Messages : 7 103
Points : 8 466
Points : 8 466
Bizarre la page n'est pas valide ?
__________________
http://blog.stealth35.com/
stealth35 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/05/2011, 09h05   #18
Nouveau Membre du Club
 
Homme
Développeur informatique
Inscription : mai 2011
Messages : 12
Détails du profil
Informations personnelles :
Sexe : Homme

Informations professionnelles :
Activité : Développeur informatique
Secteur : High Tech - Multimédia et Internet

Informations forums :
Inscription : mai 2011
Messages : 12
Points : 27
Points : 27
Re, désolé de ne pas avoir répondu plus tôt, les pages ne sont pas toujours valides en effet, la solution que j'ai proposée au dessus est correcte niveau performance et répond à mes attentes donc je pense que je vais laisser tel quel.

Merci de ton aide
CyPh3rZz est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 11h38.


 
 
 
 
Partenaires

Hébergement Web