创建一个忽略<code> blocks</code>内所有内容的正则表达式

时间:2012-01-26 23:29:24

标签: javascript jquery regex

我将表情符号添加到用户输入中:

function emoticons(html){
    for(var emoticon in emotes){
        for(var i = 0; i < emotes[emoticon].length; i++){
            // Escape bad characters like )
            var r = RegExp.escape(emotes[emoticon][i]);
            // Set the regex up to replace all matches
            r_escaped = new RegExp(r, "g");
            // Replace the emote with the image
            html = html.replace(r_escaped,"<img src=\""+icon_folder+"/face-"+emoticon+".png\" class=\"emoticonimg\" />");
        }
    }
    return html;
}

问题是有时用户输入是<code>xxx</code>块。有没有办法让表情符号函数忽略代码块中的所有内容(如果它们存在)。因为它们不会永远存在吗?

由于

1 个答案:

答案 0 :(得分:1)

为了轻松完成此操作,我只使用文本节点(非序列化HTML)并跳过code元素。

您标记了它,因此有一些jQuery便捷代码可以简化实用程序功能的跨浏览器问题。但是,很容易修改它以便在没有jQuery的情况下工作。

var searchText = function(parentNode, regex, callback, skipElements) {

    skipElements = skipElements || ['script', 'style'];

    var node = parentNode.firstChild;

    do {

        if (node.nodeType == 1) {

            var tag = node.tagName.toLowerCase();

            if (~$.inArray(tag, skipElements)) {
                continue;
            }

            searchText.call(this, node, regex, callback);

        } else if (node.nodeType == 3) {
            while (true) {

                // Does this node have a match? If not, break and return. 
                if (!regex.test(node.data)) {
                    break;
                }

                node.data.replace(regex, function(match) {

                    var args = $.makeArray(arguments),
                        offset = args[args.length - 2],
                        newTextNode = node.splitText(offset);

                    callback.apply(window, [node].concat(args));
                    newTextNode.data = newTextNode.data.substr(match.length);
                    node = newTextNode;

                });
            }
        }
    } while (node = node.nextSibling);
};

searchText($('body')[0], /:\)/, function(node, match) {
    var img = $('<img />')[0];
    img.src = 'http://www.gravatar.com/avatar/80200e1488ab252197b7f0f51ae230ef?s=32&d=identicon&r=PG';
    img.alt = match;
    node.parentNode.insertBefore(img, node.nextSibling);
}, ['code']);

jsFiddle

我最近写了这个函数,它应该做你希望实现的目标。