Der Versuch, die Links auf einer Seite zu finden.
mein Regex ist:
/<a\s[^>]*href=(\"\'??)([^\"\' >]*?)[^>]*>(.*)<\/a>/
scheint aber an zu scheitern
<a title="this" href="that">what?</a>
Wie würde ich meine Regex ändern, um mit href umzugehen, das nicht als erstes in einem Tag steht
Zuverlässiges Regex für HTML ist schwierig . So geht es mit DOM :
$dom = new DOMDocument;
$dom->loadHTML($html);
foreach ($dom->getElementsByTagName('a') as $node) {
echo $dom->saveHtml($node), PHP_EOL;
}
Das obige würde die "outerHTML" aller A
-Elemente in der $html
-Zeichenfolge finden und ausgeben.
Um get alle Textwerte des Knotens zu erhalten, müssen Sie dies tun
echo $node->nodeValue;
Um check wenn das href
-Attribut vorhanden ist, können Sie dies tun
echo $node->hasAttribute( 'href' );
Get das href
-Attribut, das Sie ausführen würden
echo $node->getAttribute( 'href' );
Um ändern das href
-Attribut, das Sie ausführen würden
$node->setAttribute('href', 'something else');
Um entfernen das href
-Attribut, das Sie ausführen würden
$node->removeAttribute('href');
Sie können das Attribut href
auch direkt mit XPath abfragen.
$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
}
Siehe auch:
Auf einer Nebenbemerkung: Ich bin sicher, dass es sich um ein Duplikat handelt und Sie können die Antwort irgendwo hier finden
Ich stimme Gordon zu, Sie MÜSSEN einen HTML-Parser verwenden, um HTML zu parsen. Wenn Sie wirklich einen Regex wollen, können Sie diesen ausprobieren:
/^<a.*?href=(["\'])(.*?)\1.*$/
Dies entspricht <a
am Anfang der Zeichenfolge, gefolgt von einer beliebigen Anzahl beliebiger Zeichen (nicht gierig) .*?
, dann href=
, gefolgt von dem Link, der entweder von "
oder '
umgeben ist.
$str = '<a title="this" href="that">what?</a>';
preg_match('/^<a.*?href=(["\'])(.*?)\1.*$/', $str, $m);
var_dump($m);
Ausgabe:
array(3) {
[0]=>
string(37) "<a title="this" href="that">what?</a>"
[1]=>
string(1) """
[2]=>
string(4) "that"
}
Das Muster, nach dem Sie suchen möchten, ist das Link-Ankermuster wie (etwas):
$regex_pattern = "/<a href=\"(.*)\">(.*)<\/a>/";
warum passt ihr nicht einfach zusammen?
"<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);
?>
dann
$ php test.php
array(2) {
[0]=>
array(1) {
[0]=>
string(27) "<a title="this" href="that""
}
[1]=>
array(1) {
[0]=>
string(4) "that"
}
}
was funktioniert. Ich habe gerade die ersten Fangklammern entfernt.
Für denjenigen, der die Lösungen mit SimpleXML immer noch nicht einfach und schnell erhält
$a = new SimpleXMLElement('<a href="www.something.com">Click here</a>');
echo $a['href']; // will echo www.something.com
Es arbeitet für mich
Ich bin nicht sicher, was Sie hier tun möchten, aber wenn Sie versuchen, den Link zu überprüfen, schauen Sie sich PHP_filter_var () an.
Wenn Sie wirklich einen regulären Ausdruck verwenden müssen, überprüfen Sie dieses Tool. Es kann hilfreich sein: http://regex.larsolavtorvik.com/
Mit Ihrer Regex habe ich es ein wenig an Ihre Bedürfnisse angepasst.
<a.*?href=("|')(.*?)("|').*?>(.*)<\/a>
Ich persönlich schlage vor, dass Sie einen HTML-Parser verwenden
EDIT: Getestet
Schneller Test: <a\s+[^>]*href=(\"\'??)([^\1]+)(?:\1)>(.*)<\/a>
scheint den Trick zu tun, wobei das erste Match "oder" ist, das zweite der 'href'-Wert' und 'das dritte und' was? '.
Der Grund, warum ich die erste Übereinstimmung von "/" dort belassen habe, ist, dass Sie es verwenden können, um später auf das schließende "/" zu verweisen, also ist es dasselbe.
Live-Beispiel unter: http://www.rubular.com/r/jsKyK2b6do
preg_match_all ("/ (]>) (. ?) (</ a) /", $ content, $ impmatches, PREG_SET_ORDER);
Es wird getestet und holt alle Tags aus einem beliebigen HTML-Code.
Folgendes funktioniert für mich und gibt sowohl href
als auch value
des Anchor-Tags zurück.
preg_match_all("'\<a.*?href=\"(.*?)\".*?\>(.*?)\<\/a\>'si", $html, $match);
if($match) {
foreach($match[0] as $k => $e) {
$urls[] = array(
'anchor' => $e,
'href' => $match[1][$k],
'value' => $match[2][$k]
);
}
}
Das mehrdimensionale Array mit dem Namen $urls
enthält jetzt einfach zu verwendende assoziative Unterarrays.