Mailinglisten-Archive |
Ralf Eggert wrote: > Hallo Yannik, > > danke für deine Mühe. Habe mittlerweile den Holzhammer raus geholt und > das Ganze anders aufgezogen: > > ------------------------------------------------------------------------ > preg_match_all( > '=(http:|https:)//[^ )\r\n!<"\']++=i', $htmlBody, $linkList > ); > > $linkList = array_unique($linkList[0]); > > if (count($linkList) > 0) > { > foreach ($linkList as $key => $link) > { > if (preg_match_all( > '^<a(.*)' . $link . '(.*)>(.*)</a>^iU', $htmlBody, $linkListSingle 1. Solltest du $link escapen bevor du es einfach in eine preg-funktion schmeißt: preg_quote($link) 2. Muss ich dich trotzdem enttäuschen. Versuch's mal mit diesen inputs: $htmlBody='<a href="http://foo.bar">http://foo.bar</a> http://foo.bar'; $htmlBody='<img src="http://foo.bar" />'; Bei ersterem wird der zweite Link nicht klickbar gemacht und bei dem zweiten... Naja... Das Bild ist danach hin. > ------------------------------------------------------------------------ > > D.h. zuerst werden alle Links gefunden, die mit http oder https > beginnen. Danach wird dann für jeden einzelnen Link geprüft, ob er sich > innerhalb eines <a> Tags befinden. Wenn nein, wird er ersetzt. Ansonsten > eben nicht. > > Performancemäßig ist das sicherlich auch suboptimal, aber es > funktioniert. Sogar bei sowas Ekelhaftem wie ein OnClick, um ein Popup > zu öffnen... onclick? Aber auch nur wenn sich das onclick in einem <a>-tag befindet... > > Danke und Gruss, > > Ralf Ich habe da auch nochmal was gebastelt. Ist auch garnicht so lang, wenn du dir die Kommentare wegdenkst, sollte zumindest /relativ/ performant sein und tut was es soll. Mir fällt zumindest gerade nichts ein, wie man den folgenden qt verwirren kann: snip --- preg_match_all( '=(?:http:|https:)//[^ )\r\n!<"\']++=i', $htmlBody, $linkList, PREG_OFFSET_CAPTURE); $newlist = array(); foreach($linkList[0] as $listItem) { $newlist[$listItem[1]] = $listItem[0]; } krsort($newlist); foreach($newlist as $offset => $link) { $linkLen = strlen($link); // Is the link within an attribute of a tag? if (($nextClosePos = strpos($htmlBody, '>', $offset + $linkLen)) !== false) { // It could be. There is a > in the sourcecode somewhere following the link // check if it is the closing tag of our link $nextOpeningTag = strpos($htmlBody, '<', $offset + $linkLen); if ($nextOpeningTag === false || $nextOpeningTag > $nextClosePos) { // now we proved that there is no opening tag before our tag that we found closes. // Thus we are in an attribute and we ignore that one. continue; } // If we made it to this point, we ware not in an attribute } // Is there a closing tag behind that one? if (($closeTagPos = strpos($htmlBody, '</a', $offset + $linkLen)) !== false) { echo "Found a closing tag at pos $closeTagPos\nchecking ", substr($htmlBody, $offset + $linkLen, $closeTagPos - $offset - $linkLen), "\n"; // yes, there is a closing tag behind that one. Check if that closing-tag belongs to this link // We do this by checking if there is an <a\s between the end of the link and the </a we found // if there is none, then this element has already got an <a> tag and so we ignore it if (!preg_match('/<a(?:\s|>)/', substr($htmlBody, $offset + $linkLen, $closeTagPos - $offset - $linkLen))) continue; } // We need to add the tag $htmlBody = substr($htmlBody, 0, $offset).'<a href="'.$link.'">'.$link.'</a>'.substr($htmlBody, $offset + $linkLen); } --- /snip Code comes with 14-days-money back guarantee - oh wait, it's free :-). Yannik
php::bar PHP Wiki - Listenarchive