2010-01-09 7 views
0

J'essaie de récupérer le texte d'un lien à partir d'un fichier HTML. Chaque lien a une classe spécifique qui lui est appliquée, mais les URL sont différentes.Récupérer le texte entre les balises A

Je donne les résultats suivants:

... 
<a class="fetch-me" href="products/1">Find ME!!!</a> 
... 
<a class="fetch-me" href="products/2">Me too!</a> 
... 

J'utilise le code PHP suivant, mais toujours obtenir plus que ce que je veux:

preg_match_all('<a class="fetch-me" href=".*">(.*)</a>)siU', $string, $matching_data); 
+4

Ne jamais analyser le HTML avec des expressions régulières. Si vous le faites, Chuck Norris vous traquera! http://stackoverflow.com/questions/590747/using-regular-expressions-to-parse-html-why-not – johnnyArt

+1

N'est-ce pas un doublon de toutes les autres questions d'expressions régulières ici sur Stack Overflow? –

+3

Ouais. Et parce que quelqu'un doit le faire: http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags –

Répondre

3
<?php 

$str = ' 
<a class="fetch-me" href="products/1">Find ME!!!</a> 
... 
<a class="fetch-me" href="products/2">Me too!</a> 
'; 

$doc = new DOMDocument(); 
$doc->loadHTML($str); 
$xp = new DOMXpath($doc); 
$query = $xp->evaluate('//a[@class="fetch-me"]'); 

if ($query->length > 0) { 
    foreach ($query as $anchor) { 
    echo $anchor->nodeValue . '<br>'; 
    } 
} 

Vous pouvez également utiliser @contains en combinaison avec @class si plusieurs valeurs de classe d'importance, vous pouvez toujours utiliser une enveloppe de haut niveau pour Abstraite DOM ainsi.

+1

Ceci est la réponse.Ignorez ma réponse (autre que la partie ne pas utiliser d'expressions rationnelles), et utilisez ceci. Je ne connais pas PHP, donc je ne peux pas écrire un exemple d'utilisation de leur analyseur HTML et des bibliothèques XPath en haut de ma tête, mais dans n'importe quelle langue, la réponse est d'utiliser l'analyseur HTML ou XML qui déjà existe dans votre langue. –

0

Qu'en est-il quelque chose comme:

/<a[^>]*([^<]*)<\/a>/siU 
0

Si vous devez utiliser une regex, utilisez .*? au lieu de .*. *? est la version non-greedy de *; c'est-à-dire, plutôt que de correspondre autant que possible, cela correspond aussi peu que possible.

(Soit dit en passant, don't try matching HTML or XML with regular expressions, de cette façon se trouve madness Au lieu de cela, essayez d'utiliser un Si vous ne disposez pas d'un analyseur HTML, exécutez par HTML Tidy et utiliser un analyseur XML analyseur HTML ou XML Voir meder's answer pour savoir comment... pour le faire en PHP.).

+1

Je dirais que regex est ok pour un si petit et spécifique tâche (où rien ne peut vraiment aller mal). Mais je vais probablement me faire tuer pour avoir dit ça. –

+2

Clairement, quelque chose peut mal se passer, car il a du mal à faire fonctionner son regex; ça consomme trop d'intrants. Et même s'il corrige cela, il y aura des balises avec des espaces supplémentaires qu'il n'a pas pris en compte, ou des arguments dans un ordre différent, ou un nombre quelconque d'autres problèmes. Au moment où vous vous fixez regex pour tenir compte de toutes ces variations, il est beaucoup plus facile de lancer votre entrée via un vrai analyseur, et sélectionnez votre élément en utilisant l'expression XPath 'a [@ class =" fetch-me "] 'ou une requête CSS' a.fetch-me' (en fonction de la prise en charge de votre bibliothèque d'analyseurs HTML ou XML). –

+1

L'analyse HTML et XML est un problème résolu. Les bibliothèques ont été écrites. Pourquoi réinventer la roue? Utilisez simplement les bibliothèques qui existent déjà! http://docs.php.net/manual/fr/class.domxpath.php –

0

une façon

$str= <<<A 
blah blah 
blah 
... 
<a class="fetch-me" href="products/1">Find ME!!!</a> 
<a class="fetch-me" href="products/2">Me too!</a> 
blah 
blah 
<a class="fetch-me" 
      href="products/1">Find me, i am at next line!!!</a> blah blah 
A; 
$s = explode("</a>",$str); 
foreach ($s as $k){ 
    if (strpos($k,"href") !==FALSE){ 
     print "--> ". preg_replace("/^.*href=\".*\">|\">.*/sm","",$k)."\n"; 
    } 
} 

sortie

$ php test.php 
--> Find ME!!! 
--> Me too! 
--> Find me, i am at next line!!! 

Idéalement, vous devez utiliser un analyseur réel, comme tout le monde dit d'autre.

0

J'ai essayé toutes ces réponses et tout le monde a probablement raison. Je vais refactoriser pour utiliser HTML Tidy et un vrai analyseur.

Merci pour les suggestions.

Questions connexes