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 28/03/2011, 18h02   #1
Membre du Club
 
Inscription : août 2005
Messages : 171
Détails du profil
Informations forums :
Inscription : août 2005
Messages : 171
Points : 40
Points : 40
Par défaut Vaut-il mieux une règle complexe, ou plusieurs simples?

Bonjour,

Je dois "crawler" de nombreuses pages de sites afin de récupérer leur contenu (avec l'accord des intéressés, bien entendu), puis récupérer certaines données contenues dans ces pages.
Le problème est que j'ai une 30 aine de données à récupérer par page, et j'hésite entre faire 3 ou 4 preg_match() assez complexes, mais récupérant une 10aine de données par expression, ou une preg_match par donnée afin d'avoir des règles beaucoup plus simples.

Voici un exemple :
Code :
1
2
3
					preg_match('`<h1>(.*) \([0-9]+\)</h1>.*<p />(.*)</div>.*<td>Nombre de personnes : ([-0-9]+)</td>.*<td>Terrain : (-|[ 0-9]*)(?: m²)?</td>'.
								'.*<div class="titre">.*phone : ([ 0-9]*)<br />'.
								'.*href="mailto:(.*)".*</a><br />(.*)<br />([0-9]+) (.*)<br />`Uis', $codeHtml, $matches);
D'après-vous, quelle est la meilleure solution : créer quelques règles assez complexes (afin de limiter le nombre de fois où le fichier sera parcouru), ou créer des règles simples mais parcourir plus de fois l'ensemble du document?

Merci d'avance pour vos conseils!
ChriGoLioNaDor est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 28/03/2011, 18h40   #2
Modérateur
 
Avatar de Benjamin Delespierre
 
Benjamin Delespierre
Développeur Web
Inscription : février 2010
Messages : 2 984
Détails du profil
Informations personnelles :
Nom : Benjamin Delespierre
Âge : 24
Localisation : France

Informations professionnelles :
Activité : Développeur Web
Secteur : High Tech - Opérateur de télécommunications

Informations forums :
Inscription : février 2010
Messages : 2 984
Points : 5 016
Points : 5 016
Citation:
Je dois "crawler" de nombreuses pages de sites afin de récupérer leur contenu (avec l'accord des intéressés, bien entendu), puis récupérer certaines données contenues dans ces pages.
Alors ce ne sont pas des regexp qu'il te faut mais un DOMDocument

Renseigne-toi sur les XPath, c'est plus simple, plus rapide et plus souple que des regexp.
__________________
A la recherche d'un framework MVC facile a prendre en main ? Essayez Axiom
Nouveau: la référence d'Axiom est disponible sur GitHub (je la peaufine en ce moment même).

Un problème correctement identifié est à moitié résolu, évitez de poster l'intégralité de votre code avec pour seule explication "ça ne marche pas...".
Pour identifier correctement vos problèmes PHP, utilisez la gestion des erreurs et xdebug.

Les boutons et existent, servez-vous en
Benjamin Delespierre est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 29/03/2011, 17h26   #3
Membre du Club
 
Inscription : août 2005
Messages : 171
Détails du profil
Informations forums :
Inscription : août 2005
Messages : 171
Points : 40
Points : 40
Bonjour et merci pour ta réponse.

J'ai commencé à me documenter sur XPath, et si j'ai bien compris, cela permets de "retourner" le contenu d'un ou plusieurs éléments dans le document, comme le contenu d'un bloc <div> donné.

Par contre, je ne vois pas comment récupérer différents éléments au sein d'un même conteneur, sans passer par une expression régulière.
Par exemple, comment récupérer le mot "maison", le prix (500), et la ville (Paris) dans 3 variables différentes, sans passer par une expression régulières, dans le cas ci-dessous :
Code :
1
2
3
<div class="prix">
	Loue Maison à 500 &euro; sur Paris
</div>
Je me doute que de toutes façons le champs de recherche serait réduit au contenu d'un bloc grâce à XPath, au lieu de l'ensemble du document, ce qui devrait fortement réduire le temps de recherche, mais je suis curieux de savoir s'il existe une meilleure solution
ChriGoLioNaDor est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/03/2011, 17h57   #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
la tu sort du XML donc un regex est éventuellement adapter, ton vrai problème a la base c'est quoi ?
__________________
http://blog.stealth35.com/
stealth35 est déconnecté   Envoyer un message privé Réponse avec citation 01
Vieux 29/03/2011, 18h35   #5
Membre du Club
 
Inscription : août 2005
Messages : 171
Détails du profil
Informations forums :
Inscription : août 2005
Messages : 171
Points : 40
Points : 40
Mon objectif est de créer un crawler qui récupère les données de fiches afin de les afficher autre part de manière totalement automatisée. L'objectif est multiple : avoir des données à jour, éviter les erreurs qui pourraient survenir en cas de saisie manuelle, et enfin leur éviter d'avoir à faire cette saisie (ou de devoir envoyer un fichier régulièrement listant les données).

Je dois donc récupérer pas mal d'informations contenues sur ces pages afin de les enregistrer (ou mettre à jour ces infos) sur le site donc je m'occupe. Et bien entendu j'essaie de faire ça de la façon la plus efficace possible pour limiter le temps d'exécution.
ChriGoLioNaDor est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/03/2011, 19h24   #6
Modérateur
 
Avatar de s.n.a.f.u
 
Homme
Développeur Web
Inscription : août 2006
Messages : 2 700
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 37
Localisation : France, Loire Atlantique (Pays de la Loire)

Informations professionnelles :
Activité : Développeur Web

Informations forums :
Inscription : août 2006
Messages : 2 700
Points : 3 357
Points : 3 357
Salut,

La réponse sera facile : ça dépend !

La technique la plus performante dépendra d'une part de tes motifs et d'autre part du volume des fichiers à analyser.

Seuls les tests pourront t'aider à choisir.

La regex que tu donnes est d'une complexité modérée et pourrait convenir.
Il conviendra de bien analyser tes quantificateurs et leur comportement "greedy" ou non, ce qui aura un impact sûrement significatif.

Désolé de ne pouvoir être plus précis, un exemple de fichier à analyser pourrait me permettre de compléter ma réponse...
__________________
  • Avant de poser une question, n'hésitez pas à chercher dans la FAQ et les forums
  • Merci d'utiliser les balises de code (# dans l'éditeur)
  • Si votre problème est réglé, merci d'utiliser le bouton
S.N.A.F.U
s.n.a.f.u est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/03/2011, 19h26   #7
Modérateur
 
Avatar de s.n.a.f.u
 
Homme
Développeur Web
Inscription : août 2006
Messages : 2 700
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 37
Localisation : France, Loire Atlantique (Pays de la Loire)

Informations professionnelles :
Activité : Développeur Web

Informations forums :
Inscription : août 2006
Messages : 2 700
Points : 3 357
Points : 3 357
Citation:
Envoyé par ChriGoLioNaDor Voir le message
Par contre, je ne vois pas comment récupérer différents éléments au sein d'un même conteneur, sans passer par une expression régulière.
Par exemple, comment récupérer le mot "maison", le prix (500), et la ville (Paris) dans 3 variables différentes, sans passer par une expression régulières, dans le cas ci-dessous :
Code :
1
2
3
<div class="prix">
	Loue Maison à 500 &euro; sur Paris
</div>
Une regex pourrait être utile sur cet exemple si le format est fixé, c'est à dire que tu es sûr qu'il ressemble à "Loue X à Y euros sur Z", ce dont je doute...
__________________
  • Avant de poser une question, n'hésitez pas à chercher dans la FAQ et les forums
  • Merci d'utiliser les balises de code (# dans l'éditeur)
  • Si votre problème est réglé, merci d'utiliser le bouton
S.N.A.F.U
s.n.a.f.u est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/03/2011, 20h18   #8
Membre du Club
 
Homme Patrick Portal
Étudiant
Inscription : novembre 2010
Messages : 31
Détails du profil
Informations personnelles :
Nom : Homme Patrick Portal
Localisation : France

Informations professionnelles :
Activité : Étudiant
Secteur : Communication - Médias

Informations forums :
Inscription : novembre 2010
Messages : 31
Points : 57
Points : 57
C'est une question que je me pose en ce moment car je dois fouiner dans 2 millions de grosses pages en local et mon script Perl basé sur des regex me demande 2 jours, comme quoi la performance c'est important aussi !

Pour le XML, il y a plusieurs langages qui ont été créés pour ça, j'ai eu l'occasion de manipuler un peu Full Text 1.0 avec le xQuery je pense donc que c'est possible.
http://www.w3.org/TR/xpath-full-text-10/

Une chose est sûr, l'apprentissage des regex sera bien plus rapide que celui de xPath/ xQuery et de tous ses dérivés. Il pourra être en revanche un peu plus puissant sur de grosse pages mais en fait je n'ai pas bien idée et je suis pourtant en pleins dedans...
patate_violente est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/03/2011, 08h01   #9
Membre actif
 
Inscription : février 2009
Messages : 150
Détails du profil
Informations forums :
Inscription : février 2009
Messages : 150
Points : 198
Points : 198
Citation:
Vaut-il mieux une règle complexe, ou plusieurs simples ?
A priori une seule règle complexe sera plus performante.

Comme dit par s.n.a.f.u, il y a peu etre certain quantificateur à optimiser (* en + par exemple), et je vois mal comment faire une meilleur regex vu toutes les données à récup.

Citation:
fouiner dans 2 millions de grosses pages
Oui c'est sur que ça doit prendre un certain temps, mais 2jours est peu etre un peu excessif selon ta recherche et surtout ta bécane.

Le meilleur moyen pour gagner en perf est de passer à un langage de plus bas niveau. (ou peu etre d'avoir un sparc )

Faites des benchs, optimisez vos regex, il n'y a pas de mystère quand on brasse beaucoup de données, ça prend du tps...
nextdev est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/03/2011, 09h07   #10
Membre Expert
 
Homme
Inscription : janvier 2004
Messages : 1 238
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Secteur : Finance

Informations forums :
Inscription : janvier 2004
Messages : 1 238
Points : 1 421
Points : 1 421
*XPath ou DOM ne fonctionneront correctement que si ta page est valide XML. Si le HTML est mal formaté et que tu as des fermetures de balises qui manquent, je doute que ca fonctionne (et si tu as des <br> au lieu de <br/> c'est pareil...)

* Pour les regexp, a priori, je dirais qu'une regexp complexe est plus performante que plusieurs regex, parce que justement il y a moins de parsing de fichiers.

Cependant, si tu écrit mal ta regexp complexe et que tu met une étoile mal placée ou autre, ca peut durer beaucoup plus longtemps et surtout être très difficile a débugger pour déterminer le problème.

Si c'est un script "one shot" (ou jetable), fait plusieurs regexp. Ca sera plus simple (donc gain en temps de développement) et si ca doit s'executer pendant 3 jours, ca prendra moins de temps que si tu dois passer 1 semaine a corriger une regexp complexe.

Si c'est un script que tu sera amené a relancer de temps en temps, tu peux faire des regexp complexe, mais je te conseille de les construire dynamiquement.
Ca rajoute un peu de complexité, mais ca simplifie la recherche de problème et le débuggage une fois que tu as mis le système en place.
L'idée est de construite tes morceaux de regexp (exemples non fonctionnels ;o) :
Code :
1
2
3
$prix=' ([0-9]+) euros';
$lieu=' a ([^ ]+)';
...
puis de les aggreger dans une seule regexp :
Code :
$regexp='#'...$prix.'.*'.$lieu...'#';
comme ca tu peux facilement commenter une partie de ta regexp pour trouver la source d'un problème.

Enfin, sache que j'ai déjà fait ce genre de choses et que si tes pages n'ont pas été générés automatiquement par le même programme, tu va tomber sur des cas d'exceptions jusqu'au dernier fichier.
Il est alors intéressant de gérer dès le début un système de parsing partiel des fichiers :
Code :
1
2
3
4
5
6
* Pour tout les fichiers a parser
   * Parse
   * Si erreur ou donnée non trouvée
      * passage au fichier suivant
   * Sinon
      * Déplacement du fichier dans un dossier "OK"
=> L'avantage c'est que tu va éviter de parser les fichiers "OK" plusieurs fois, au fur et a mesure que tu gère les exceptions.

Evidemment, si ton script est réutilisable, il faut que tu le repasse sur les fichiers OK ensuite pour vérifier que tu n'a pas "cassé" des règles en gérant les exceptions ;o)
__________________
PHP :
Regle n°1 : mysql_query(...), mysql_connect(...) et mysq_select_db(...) doivent EN DEBUG etre suivies de or die(mysql_error()); (mais jamais en production)
Regle n°2 : Mieux encore : mysql_query($requete) or die("$requete<br/>".mysql_error());
Regle n°3 : echo '<pre>';var_dump($var);echo '</pre>'; affiche le contenu et le type d'une variable.
Publiez vos textes de fantasy et de science-fiction sur http://www.cercledefaeries.com/concours/
Fladnag est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/03/2011, 14h20   #11
Membre du Club
 
Homme Patrick Portal
Étudiant
Inscription : novembre 2010
Messages : 31
Détails du profil
Informations personnelles :
Nom : Homme Patrick Portal
Localisation : France

Informations professionnelles :
Activité : Étudiant
Secteur : Communication - Médias

Informations forums :
Inscription : novembre 2010
Messages : 31
Points : 57
Points : 57
Je confirme, dans mon cas, j'ai regroupé certaines regex et le temps est nettement descendu (dans les 10% aux pronostiques)

N'acceptant pas cette durée de traitement, j'ai finalement rendu mon script dans plusieurs processus, j'utilise personnellement Perl qui se charge de tout mais si tu demandes plusieurs fois ta page php avec des paramètres différents ça fonctionnera tout aussi bien. Avec 4 et + unités de calculs tu sentiras une très nette différence.
J'ai aussi exploité mon réseau et lancé le travail de traitement des chaînes aux autres ordinateurs. Attention toutefois à ne pas faire excéder le travail du serveur pour qu'il puisse bien satisfaire les clients dans ce cas, le laisser simplement générer les pages finalement (sauf s'il en demande plus...).
Dans mon cas les 2 jours devraient être pulvérisés

Voilà donc dans le cas d'un très gros travail, et si tu as plusieurs bécanes sous la main je te conseiller aussi de décentraliser un peu le boulot, là tu auras de vrai résultats.
La remarque de Fladnag est valable sur toutes Regex d'ailleurs
patate_violente est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 31/03/2011, 07h16   #12
Membre actif
 
Inscription : février 2009
Messages : 150
Détails du profil
Informations forums :
Inscription : février 2009
Messages : 150
Points : 198
Points : 198
C'est un peu violent le traitement de 2millions de pages tirée d'un autre serveur (les deux jours de traitements viennent surement en parti de la, enfin j'ai un peu de mal a saisir comment est vraiment fait ton mini centre informatique lol)

Par curiosité, j'aimerai bien savoir ce que tu as fait pour éviter d'encombrer trop le serveur ??
nextdev est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 31/03/2011, 22h36   #13
Membre du Club
 
Homme Patrick Portal
Étudiant
Inscription : novembre 2010
Messages : 31
Détails du profil
Informations personnelles :
Nom : Homme Patrick Portal
Localisation : France

Informations professionnelles :
Activité : Étudiant
Secteur : Communication - Médias

Informations forums :
Inscription : novembre 2010
Messages : 31
Points : 57
Points : 57
c'est un traîtement un peu inhabituel j'essai de récupérer des infos sérialisés dans un système de distribution très fermé (qui propose un serveur pour générer des pages générés en Java ce qui n'est pas très pratique à l'exploitation des données dans mon cas je ne sais pas comment pensent toujours certains concepteurs...)

En fait je disais qu'il ne faut pas encombrer le serveur pour qu'il répondent aussi rapidement que possible à mes autres machines qui traitent les chaînes + le remplissable décentralisé d'une base de donnée. Je ne fais donc rien de très précis pour ne pas surcharger, je règle ça à tatons mais ça a l'avantage d'être facile à mettre en place autant pour moi que le créateur de ce post puisque c'est une appli réseau
patate_violente est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 31/03/2011, 23h38   #14
Membre Expert
 
Homme
Inscription : janvier 2004
Messages : 1 238
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Secteur : Finance

Informations forums :
Inscription : janvier 2004
Messages : 1 238
Points : 1 421
Points : 1 421
Citation:
Envoyé par patate_violente Voir le message
je ne sais pas comment pensent toujours certains concepteurs...
C'est là ou tu fais erreur, certains ne pensent pas ;o)
__________________
PHP :
Regle n°1 : mysql_query(...), mysql_connect(...) et mysq_select_db(...) doivent EN DEBUG etre suivies de or die(mysql_error()); (mais jamais en production)
Regle n°2 : Mieux encore : mysql_query($requete) or die("$requete<br/>".mysql_error());
Regle n°3 : echo '<pre>';var_dump($var);echo '</pre>'; affiche le contenu et le type d'une variable.
Publiez vos textes de fantasy et de science-fiction sur http://www.cercledefaeries.com/concours/
Fladnag est déconnecté   Envoyer un message privé Réponse avec citation 10
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 23h57.


 
 
 
 
Partenaires

Hébergement Web