用HTML元素替换文本标记

时间:2014-04-03 23:15:59

标签: javascript jquery html replace token

查看像DIV这样的HTML元素并使用HTML元素替换特定文本的最佳方法是什么。例如,假设我们有令牌[b][/b]。我想分别用<b></b>替换它们。

我最接近这个的是下面的例子。

HTML to teplace:

<div id="response">This is some [b]GREAT[/b] stuff!</div>

示例#1:

$('#response').html(function() {
    return $(this).text().replace('[b]', '<b>');
});
$('#response').html(function () {
    return $(this).text().replace('[/b]', '</b>');
});

结果#1:

  

这是一些很棒的东西!


示例#2:

$('#response').html(function() {
    return $(this).text().replace('[b]', $('<b>'));
});
$('#response').html(function () {
    return $(this).text().replace('[/b]', $('</b>'));
});

结果#2:

  

这是一些[object Object] GREAT [object Object]的东西!


期望的结果:

  

这是一些 GREAT 的东西!

两者都不起作用。前者只是将标记替换为空,后者将其替换为浏览器中的对象,而不是所需的HTML元素。

3 个答案:

答案 0 :(得分:6)

使用正则表达式应该很好:

$('#response').html(function() {
    return $(this).text().replace(/\[(\/?\w+)\]/g, "<$1>");
});

好处是所有标记都可以替换,而无需单独命名。

请注意,这为跨站点脚本攻击打开了大门!


如果您想在此过程中转换令牌(例如[b]<strong>)并将其列入白名单(并且肯定希望将其列入白名单以迁移XSS漏洞),使用回调函数作为替换函数,如下所示:

$('#response').html(function () {
    var map = {
        b: "strong",
        i: "em",
        p: "p"
    };
    return $(this).text().replace(/\[(\/?)(\w+)\]/g, function ($0, $1, $2) {
        if (map.hasOwnProperty($2)) {
            return "<" + $1 + map[$2] + ">";
        } else {
            return $0;
        }
    });
});

为了使这个成为jQuery的答案,以下是如何将所有内容转换为花哨的jQuery插件以供重用:

$.fn.extend({
    unphpbb: (function () {
        var map = {
               b: "strong",
               i: "em",
               p: "p"
            },
            tokens = /\[(\/?)(\w+)\]/g,
            replacement = function ($0, $1, $2) {
                return map.hasOwnProperty($2) ? "<" + $1 + map[$2] + ">" : $0;
            },
            replaceTokens = function (i, html) {
                return html.replace(tokens, replacement);
            };

        return function () {
            return this.html(replaceTokens);
        };
    })()
});

用作

$("#response").unphpbb();

当然,在服务器上使用bbcode解析器 并将正确的擦除HTML发送到客户端是解决此问题的首选方法。在具有上述功能的客户端上执行此操作在各方面都是劣等的。

答案 1 :(得分:1)

你的第一次努力看起来更好,但你应该在一次通话中这样做,以免在通话之间产生破碎的HTML,例如

$('#response').html(function() {
    return $(this).text().replace('[b]', '<b>').replace('[/b]', '</b>');
});

您甚至可以尝试使用此正则表达式替换

var rx = /\[(\/?[a-z]+)\]/g;
return $(this).text().replace(rx, '<$1>');

正则表达式方法还允许您定义一组允许的标记(以便不支持<script>之类的内容),例如

var rx = /\[(\/?(b|i|strong|em|u|tt))\]/g;

答案 2 :(得分:1)

您正在寻找解析基本上BBCode的内容。实现起来很简单的Patrick Gillespie wrote this JS Library

var result = XBBCODE.process({
    text: "Some bbcode to process here",
    removeMisalignedTags: false,
    addInLineBreaks: false
});
console.log("Errors: " + result.error);
console.dir(result.errorQueue);
console.log(result.html);// the HTML form of your BBCode