jQuery:如何在锚标记中包装RegEx匹配的纯文本?

时间:2012-07-26 02:19:11

标签: javascript jquery html regex

假设我有一个看起来像这样的HTML页面:

<html><body>
00123
<input value="00123">
00456
</body></html>

我想使用javascript / jQuery使它看起来像这样:

<html><body>
<a href="#00123">00123</a>
<input value="00123">
<a href="#00456">00456</a>
</body></html>

基本上我想用HTML锚标签在文档中包装正则表达式匹配的普通字符串。在这个例子中,我想做类似的事情:

$('body').html($('body').html().replace(/(00\d+)/, '<a href="#$1">$1</a>'));

使用此示例查看jsFiddle:http://jsfiddle.net/NATnr/2/

此解决方案的问题是input元素内的文本已匹配并替换。

有没有人知道如何使用javascript / jQuery以这种方式匹配和替换文档中的纯文本?

4 个答案:

答案 0 :(得分:8)

filtering contents() nodeType Fiddle仅{+ 3}}获取文本节点,然后用jQuery生成的锚元素替换它们(这些中的任何额外文本)节点将保留为文本节点):

body

the ponies

如您所知,通常使用Regex解析HTML并不是一个好主意(注意global modifier,它们是邪恶的),但是如果您要分离要解析的HTML的一部分,则遵循一个相对简单的模式,它是一个可行的选择。

编辑:在您的正则表达式中包含$('body').contents().filter(function() { return this.nodeType === 3; }).each(function() { $(this).replaceWith($(this).text().replace(/(00\d+)/g, '<a href="#$1">$1</a>')); }); 标记({{3}}),以便在单个文本节点中匹配多个锚点。

答案 1 :(得分:5)

最终解决方案最终看起来像这样:

jQuery.fn.linker = function () {
    $(this).contents()
        .filter(function() { return this.nodeType != Node.TEXT_NODE; })
        .each(function () { $(this).linker(); });
    $(this).contents()
        .filter(function() { return this.nodeType == Node.TEXT_NODE; })
        .each(function () {
            $(this).replaceWith(
                $(this).text().replace(/(00\d+)/g, '<a href="#$1">$1</a>')
            );
        });
}
$(document).ready(function () {
    $('body').linker();
});

请参阅此处的jsFiddle:http://jsfiddle.net/fr4AL/4/

感谢:

答案 2 :(得分:0)

这是来自bobince问题的相关答案:

  

你不想用正则表达式处理HTML。分配.html()的大块也是坏消息;除了序列化和重新分析大量HTML的性能缺点之外,您还将丢失不可重复的数据,如事件侦听器,表单数据和JS属性/引用。

     

这是一个允许RegExp模式匹配的纯JavaScript / DOM。 jQuery在这里并没有真正给你太多帮助,因为选择器只能选择元素,':contains'选择器是递归的,所以对我们来说不太有用。

// Find text in descendents of an element, in reverse document order
// pattern must be a regexp with global flag
//
function findText(element, pattern, callback) {
    for (var childi= element.childNodes.length; childi-->0;) {
        var child= element.childNodes[childi];
        if (child.nodeType==1) {
            findText(child, pattern, callback);
        } else if (child.nodeType==3) {
            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]);
        }
    }
}

findText(document.body, /\bBuyNow\b/g, function(node, match) {
    var span= document.createElement('span');
    span.className= 'highlight';
    node.splitText(match.index+6);
    span.appendChild(node.splitText(match.index+3));
    node.parentNode.insertBefore(span, node.nextSibling);
});

答案 3 :(得分:0)

给它一个旋转......更干净! ;)

$('input').each(function() {
    var temp;
       temp = $(this).val();
       $(this).before('<a href="#' + temp +'">' +temp+ '</a>');
});
$('body').contents().filter(function() {return this.nodeType == 3;}).remove();