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