您的位置:首页 > Web前端 > HTML

关于HTML在线编辑文本的编码与解码

2014-01-07 20:48 471 查看
很多在线编辑的网页都需要对用户输入的文本进行html的编码,避免输入的内容影响正常的网页排版,重新编辑时又需要进行对应的解码操作。用google搜索了一下,发现网上引用最多的两个函数是:

//编码
function HTMLEncode(str)
{
var s = "";
if (str.length == 0) return "";
s = str.replace(/&/g, "&");
s = s.replace(/</g, "<");
s = s.replace(/>/g, ">");
s = s.replace(/ /g, " ");
s = s.replace(/\'/g, "'");
s = s.replace(/\"/g, """);
s = s.replace(/\n/g, "<br>");
return s;
}

function HTMLDecode(str)
{
var s = "";
if (str.length == 0) return "";
s = str.replace(/&/g, "&");
s = s.replace(/</g, "<");
s = s.replace(/>/g, ">");
s = s.replace(/ /g, " ");
s = s.replace(/'/g, "\'");
s = s.replace(/"/g, "\"");
s = s.replace(/<br>/g, "\n");
return s;
}

这两个函数存在以下问题,假如用户输入的文本为:

我输入了一些html标签\n&<div>就这么多</div>


那么使用HTMLEncode的结果是:

我输入了一些html标签<br>&<div>就这么多</div>
这个结果没有问题,但是如果我用这个输出结果再执行一次HTMLEncode,结果就是:

我输入了一些html标签<br>&amp;&lt;div&gt;就这么多&lt;/div&gt;


没错!其中的&又被编码了一次,而且把<br>也进行了编码,其实理想情况下,多次调用HTMLEncode,应该结果保持不变。问题出现在HTMLEncode中的:

s = str.replace(/&/g, "&");
s = s.replace(/</g, "<");
s = s.replace(/>/g, ">");
这句话中,它没有考虑传入的字符串是否已经经过编码了,而且没有考虑<和>是不是<br>中的,所以我们将改为:
s = str.replace(/&(?!(amp;|lt;|gt;|nbsp;|quot;))/g, "&");
s = s.replace(/<(?!br>)/g, "<");
s = s.replace(/(<br)?>/g, function ($0, $1) { return ($1 ? $0 : ">"); });
第一句表示只有&后面跟的不是lt;|gt;|nbsp;|quot;这些时,才替换为&。

第二句与第一句话类似,表示<后面跟的不是br>时,才替换>为<。

第三句就比较费解了,这句想要达到的效果是当>前面的字符不是<br时替换>为>,它需要用到正则表达式中的negative lookbehind功能,但是javascript的正则表达式却不支持这以特性,如果支持的话,写起来就简单了,如下:
s = s.replace(/(?<!<br)>/g, ">");
所以在javascript中想要达到同样的效果只能使用变通的办法,replace的第二个参数可以是一个函数,可以对匹配的结果进行处理之后再返回一个替换用的字符串,其中$0,$1,$2……可以作为参数使用,分别表示匹配到的完整字符串,第一个子表达式,第二个子表达式……,所以下面这句话的意思是:
s = s.replace(/(<br)?>/g, function ($0, $1) { return ($1 ? $0 : ">"); });
先匹配>前面有<br或者没有<br(用?匹配),函数的功能是,如果前面有<br,也就是$1不为空,就使用匹配到的整个字符串$0替换(也就是没有变化),如果前面没有<br,也就是说$1为空,这时就返回>替换>。

完整的HTMLEncode和HTMLDecode如下:
function HTMLEncode(str) {
var s = "";
if (str.length == 0) return "";
s = str.replace(/&(?!(amp;|lt;|gt;|nbsp;|quot;))/g, "&");
s = s.replace(/<(?!br\>)/g, "<");
s = s.replace(/(<br)?>/g, function ($0, $1) { return ($1 ? $0 : ">"); });
s = s.replace(/ /g, " ");
s = s.replace(/\'/g, "'");
s = s.replace(/\"/g, """);
s = s.replace(/\n/g, "<br>");
return s;
}

function HTMLDecode(str) {
var s = "";
if (str.length == 0) return "";
s = str.replace(/&/g, "&");
s = s.replace(/</g, "<");
s = s.replace(/>/g, ">");
s = s.replace(/ /g, " ");
s = s.replace(/'/g, "\'");
s = s.replace(/"/g, "\"");
s = s.replace(/<br>/g, "\n");
return s;
}


顺便说一下:CSDN博客的源代码编辑真的非常糟糕!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息