Hello evryone
i need aregex code that replacing
url: http://domain.com at
link: <a href="http://domain.com" rel="nofollow">http://domain.com</a>

replace the url until space

Dani AI

Generated

asked for a regex to turn plain URLs into links without mangling existing anchors; offered a simple preg_replace and pointed at an external URL-matching resource. A simple global regex (like the one shown earlier in the thread) will match many cases, but it also easily creates nested <a> tags or breaks href attributes when run over HTML. For reliable results, operate on the HTML DOM and only transform text nodes that are not already inside an <a>, <script> or <style> element. (stackoverflow.com)

Recommended approach (keeps HTML structure intact): load the fragment with DOMDocument, use DOMXPath to select text nodes outside anchors, find URL substrings inside those nodes with a focused regex, then replace each match by inserting a new <a> element (set href and rel as needed). That avoids double-wrapping and keeps attributes safe; DOMDocument + DOMXPath are the right tools for this task. (php.net)

Example (PHP):

function linkifyHtml($html) {
    libxml_use_internal_errors(true);
    $doc = new DOMDocument();
    $doc->loadHTML(mb_convert_encoding($html, 'HTML-ENTITIES', 'UTF-8'));
    $xpath = new DOMXPath($doc);
    $nodes = $xpath->query('//text()[not(ancestor::a) and not(ancestor::script) and not(ancestor::style)]');

    $urlPattern = '/\b((?:https?|ftp):\/\/[^\s<>"\'()]+(?:\([^\s<>"\'()]*\))?)/i';

    foreach ($nodes as $node) {
        $text = $node->nodeValue;
        if (!preg_match($urlPattern, $text)) continue;

        $frag = $doc->createDocumentFragment();
        $last = 0;
        preg_match_all($urlPattern, $text, $matches, PREG_OFFSET_CAPTURE);
        foreach ($matches[0] as $m) {
            $url = $m[0]; $pos = $m[1];
            $before = substr($text, $last, $pos - $last);
            if ($before !== '') $frag->appendChild($doc->createTextNode($before));
            $a = $doc->createElement('a');
            $a->setAttribute('href', $url);
            $a->setAttribute('rel', 'nofollow');
            $a->appendChild($doc->createTextNode($url));
            $frag->appendChild($a);
            $last = $pos + strlen($url);
        }
        $rest = substr($text, $last);
        if ($rest !== '') $frag->appendChild($doc->createTextNode($rest));
        $node->parentNode->replaceChild($frag, $node);
    }
    return $doc->saveHTML();
}

Notes and troubleshooting: choose a regex that matches the schemes needed and excludes trailing punctuation; RFC 3986 defines the URI components to consider when refining the pattern. (datatracker.ietf.org) Do not rely solely on filter_var(FILTER_VALIDATE_URL) for strict validation in some older PHP releases — there was a known validation bug (CVE-2024-5458) that affected certain PHP versions; either check PHP version or use a dedicated URI library for strict parsing. Also suppress libxml warnings with libxml_use_internal_errors(true) when loading fragments, and consider PHP’s HTML5-aware parsers (Dom\HTMLDocument) on newer PHP versions for full HTML5 compliance. (nvd.nist.gov)

Recommended Answers

All 2 Replies

Member Avatar for Member #120589
$url = "";
echo preg_replace("/(http:\/\/\S+)\s*/","<a href=\"$1\" rel=\"nofollow\">$1</a>",$url);

that'll work on the simplest of urls. check out url matches, e.g. ftp, https, with querystrings and username/pw and anchor hashes etc

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.