120 votes

Saisir l'attribut href d'un élément A

Essayer de trouver les liens sur une page.

mon regex est:

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

mais semble échouer à

 <a title="this" href="that">what?</a>
 

Comment pourrais-je changer mon regex pour traiter avec href non placé en premier dans la balise a?

220voto

Gordon Points 156415

Fiable Regex HTML sont difficiles. Voici comment le faire avec DOM:

$dom = new DOMDocument;
$dom->loadHTML($html);
foreach ($dom->getElementsByTagName('a') as $node) {
    echo $dom->saveHtml($node), PHP_EOL;
}

Le ci-dessus serait de trouver et de sortie de la "outerHTML" de à tous A éléments dans l' $html chaîne de caractères.

Pour obtenir toutes les valeurs de texte du nœud, vous ne

echo $node->nodeValue; 

Pour vérifier si l' href attribut existe, vous pouvez le faire

echo $node->hasAttribute( 'href' );

Pour obtenir l' href attribut que vous souhaitez faire

echo $node->getAttribute( 'href' );

Pour changer l' href attribut que vous souhaitez faire

$node->setAttribute('href', 'something else');

Pour supprimer l' href attribut que vous souhaitez faire

$node->removeAttribute('href'); 

Vous pouvez également interroger pour l' href attribut directement avec XPath

$dom = new DOMDocument;
$dom->loadHTML($html);
$xpath = new DOMXPath($dom);
$nodes = $xpath->query('//a/@href');
foreach($nodes as $href) {
    echo $href->nodeValue;                       // echo current attribute value
    $href->nodeValue = 'new value';              // set new attribute value
    $href->parentNode->removeAttribute('href');  // remove attribute
}

Voir aussi:

Sur une note: je suis sûr que c'est un doublon et vous pouvez trouver la réponse quelque part ici

19voto

M42 Points 31888

Je suis d'accord avec Gordon, vous DEVEZ utiliser un analyseur HTML pour analyser le code HTML. Mais si vous voulez vraiment une regex, vous pouvez essayer celui-ci:

 /^<a.*?href=(["\'])(.*?)\1.*$/
 

Cela correspond à <a au début de la chaîne, suivi d'un nombre quelconque de caractères (non glouton) .*? puis href= suivi du lien entouré de " ou '

 $str = '<a title="this" href="that">what?</a>';
preg_match('/^<a.*?href=(["\'])(.*?)\1.*$/', $str, $m);
var_dump($m);
 

Sortie:

 array(3) {
  [0]=>
  string(37) "<a title="this" href="that">what?</a>"
  [1]=>
  string(1) """
  [2]=>
  string(4) "that"
}
 

4voto

plutov.by Points 8991

Le modèle que vous souhaitez rechercher serait le modèle d'ancrage de lien, comme (quelque chose):

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

3voto

Aif Points 4603

pourquoi ne pas juste correspondre

 "<a.*?href\s*=\s*['"](.*?)['"]"

<?php

$str = '<a title="this" href="that">what?</a>';

$res = array();

preg_match_all("/<a.*?href\s*=\s*['\"](.*?)['\"]/", $str, $res);

var_dump($res);

?>
 

puis

 $ php test.php
array(2) {
  [0]=>
  array(1) {
    [0]=>
    string(27) "<a title="this" href="that""
  }
  [1]=>
  array(1) {
    [0]=>
    string(4) "that"
  }
}
 

qui fonctionne. Je viens de retirer les premières accolades de capture.

2voto

CharlesLeaf Points 2572

Test rapide : `` semble faire l’affaire, avec le 1er match étant "ou", le second le « href » valeur « qui » et le troisième le « quoi ? ».

La raison pour laquelle j’ai quitté le premier match de « / "là-dedans est que vous pouvez l’utiliser pour backreference plus tard pour la fermeture « /" donc c’est la même chose.

Voir l’exemple direct sur : http://www.rubular.com/r/jsKyK2b6do

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X