Mailinglisten-Archive |
Ralf Eggert wrote: > Moin Yannik, > >> =((http:|https:)//[^ )\r\n!<"]++)(?!")=i > > Ich habe das nun mal ausprobiert. Habe auch den Beispieltext ein wenig > geändert, um zu sehen, was er findet: > > ------------------------------------------------------------------------ > Hier steht ein http:/www.link.de und hier steht noch ein <a > href="http:/www.anderer-link1.de">http:/www.anderer-link2.de</a> > ------------------------------------------------------------------------ > > Mit dem Ausdruck findet er http:/www.link.de und > http:/www.anderer-link2.de, was ja auch logisch ist. Ich habe nun ein > wenig herumprobiert, ob ich (?!") so abändern kann, dass er auch ein > folgendes < ausschliesst. Bin daran leider gescheitert.... :-( > >> Sowas könntest du noch verhindern in dem du dein regex dazu ausbaust zu >> erkennen, ob es sich in einem tag befindet (vor dem nächsten > muss ein >> < kommen oder es darf kein > mehr kommen). > > Würde ich gerne machen, wenn ichs kapiert habe... ;-) > >> Hier steht noch ein bißchen was über Assertions: >> http://www.regenechsen.de/phpwcms/index.php?regex_allg_option > > Dann habe ich mir deinen Link durchgelesen und was von negativer > Lookbehind-Assertion gelesen. Und siehe da! Folgende Regex löst mein > Problem. > > =((?<!>)(http:|https:)//[^ )\r\n!<"]++)(?!")=i > > Nur das von dir angesprochene Problem mit der URL im ALT-Text habe ich > damit noch nicht gelöst. Aber das könnte ich versuchen, vorher > rauszufiltern. Und ich habe ein Problem, wenn der Link unter einem <br > /> steht, dann wird der auch nicht gefunden. Mistmüll! Hier mal die etwas längere und vermutlich auch extrem unperformante Lösung, die dafür bombensicher (naja... Fast. Der Regex in Zeile 13 ist möglicherweise noch nicht so perfekt. Mir fällt aber gerade kein Potential für Probleme damit ein) sein sollte: snip --- <?php $doc = new DOMDocument; $doc->loadHTML('<u>f<a href="http://asdf.com/">f</a>f http://example.com sdf <a href="https://asdf.com/sadf">https://asdf.com/sadf</a></u>'); function replaceLinks(DOMDocument $doc, DOMNode $node) { do { if ($node->nodeType == XML_TEXT_NODE) { $newNodes = array(); $value = $node->nodeValue; while(preg_match('/(.*)(https?:\/\/[^\s]+)/', $value, $matches)) { if (!empty($matches[1])) $newNodes[] = $doc->createTextNode($matches[1]); $newNodes[] = $link = $doc->createElement('a'); $link->setAttribute('href', $matches[2]); $link->appendChild($doc->createTextNode($matches[2])); $value = substr($value, strlen($matches[0])); } if (!empty($newNodes)) { if (!empty($value)) $newNodes[] = $doc->createTextNode($value); foreach($newNodes as $newNode) $node->parentNode->insertBefore($newNode, $node); $oldNode = $node; $node = $newNodes[count($newNodes) -1]; $oldNode->parentNode->removeChild($oldNode); } } elseif ($node->hasChildNodes() && $node->nodeName != 'a') replaceLinks($doc, $node->firstChild); }while(($node = $node->nextSibling) != null); } replaceLinks($doc, $doc); echo $doc->saveHTML(); ?> --- /snip Sonderlich ausführlich getestet habe ich das jetzt nicht... Wenn ich nachher noch was Zeit habe beschäftige ich mich mal mit der Verbesserung der Regexlösung. > > Danke und Gruss, > > Ralf Yannik
php::bar PHP Wiki - Listenarchive