Javascript:查找文档中的URL

5 javascript regex url dom

如何在文档中找到URL(即www.domain.com),并将其放在锚点内:<a href ="www.domain.com"> www.domain.com </ a>

HTML:

Hey dude, check out this link www.google.com and www.yahoo.com!
Run Code Online (Sandbox Code Playgroud)

JavaScript的:

(function(){var text = document.body.innerHTML;/*do replace regex => text*/})();
Run Code Online (Sandbox Code Playgroud)

输出:

Hey dude, check out this link <a href="www.google.com">www.google.com</a> and <a href="www.yahoo.com">www.yahoo.com</a>!
Run Code Online (Sandbox Code Playgroud)

bob*_*nce 6

首先,www.domain.com它不是URL,它是主机名,和

<a href="www.domain.com">
Run Code Online (Sandbox Code Playgroud)

将无法工作 - 它将查找相对于当前页面.com调用的文件www.domain.

在一般情况下,不可能突出显示主机名,因为几乎任何东西都可以是主机名.您可以尝试突出显示"www.something.dot.separated.words",但它并不是那么可靠,并且有许多站点不使用www.主机名前缀.我试着避免这种情况.

/\bhttps?:\/\/[^\s<>"`{}|\^\[\]\\]+/;
Run Code Online (Sandbox Code Playgroud)

这是一种非常自由的模式,您可以将其用作检测HTTP URL的起点.根据您所获得的输入类型,您可能希望缩小其允许的范围,并且可能值得检测尾随字符,如URL .!URL的有效部分,但实际上通常不是.

(你可以使用一个|允许任何 URL语法www.hostname语法,如果你喜欢.)

无论如何,一旦你确定了首选模式,你就需要在页面上的文本节点中找到该模式.不要在innerHTML标记上运行正则表达式.您最终会通过尝试标记href="http://something"已经在标记内的每个内容来彻底破坏页面.替换innerHTML内容时,您还将销毁任何现有的JavaScript引用,事件或表单字段值.

通常,regexp无法以任何可靠的方式处理HTML.因此,利用浏览器已经将HTML解析为元素和文本节点的事实,并只查看文本节点.您还希望避免查看内部<a>元素,因为当URL已经在链接中时将其标记为链接是愚蠢的(并且无效).

// Mark up `http://...` text in an element and its descendants as links.
//
function addLinks(element) {
    var urlpattern= /\bhttps?:\/\/[^\s<>"`{}|\^\[\]\\]+/g;
    findTextExceptInLinks(element, urlpattern, function(node, match) {
        node.splitText(match.index+match[0].length);
        var a= document.createElement('a');
        a.href= match[0];
        a.appendChild(node.splitText(match.index));
        node.parentNode.insertBefore(a, node.nextSibling);
    });
}

// Find text in descendents of an element, in reverse document order
// pattern must be a regexp with global flag
//
function findTextExceptInLinks(element, pattern, callback) {
    for (var childi= element.childNodes.length; childi-->0;) {
        var child= element.childNodes[childi];
        if (child.nodeType===Node.ELEMENT_NODE) {
            if (child.tagName.toLowerCase()!=='a')
                findTextExceptInLinks(child, pattern, callback);
        } else if (child.nodeType===Node.TEXT_NODE) {
            var matches= [];
            var match;
            while (match= pattern.exec(child.data))
                matches.push(match);
            for (var i= matches.length; i-->0;)
                callback.call(window, child, matches[i]);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)