一行代码实现 unescape html
实体符
在 HTML 中,某些字符是预留的。在 HTML 中不能使用小于号(<)和大于号(>),这是因为浏览器会误认为它们是标签。如果希望正确地显示预留字符,我们必须在 HTML 源代码中使用字符实体(character entities)。如需显示小于号,我们必须这样写:
<
或<
或者<
;
不同的表现格式是根据原始字符的 ascii 码来进行关联的。其中,<
符号对应的十进制 ascii 为 60,对应的十六进制为 3c。
因此,对实体符的解码,需要匹配符合格式的&#
来进行解码。
解码
根据格式得出正则:
/&#(x)?([\w\d]{0,5});/ig
然后进行字符串替换
/**
* 解码 html 实体符
* @param str {String} html 实体符
* @returns {String}
*/
var unescapeHTML = function (str) {
return str.replace(/&#(x)?([\w\d]{0,5});/ig, function (full, hex, code) {
return String.fromCharCode(parseInt(code, hex ? 16 : 10));
});
};
此时,一些如<
这样的字符是无法正常替换的,需要建立一个 map 表来进行处理。
/**
* 解码 html 实体符 map
* @type {Object}
*/
var unescapeHTMLMap = {
'&': /&/g,
'<': /</g,
'>': />/g,
'"': /"/g,
'\'': /'/g,
'/': ///g
};
/**
* 解码 html 实体符
* @param str {String} html 实体符
* @returns {String}
*/
var unescapeHTML = function (str) {
str = str.replace(/&#(x)?([\w\d]{0,5});/ig, function (full, hex, code) {
return String.fromCharCode(parseInt(code, hex ? 16 : 10));
});
for (var src in unescapeHTMLMap) {
str = str.replace(unescapeHTMLMap[src], src);
}
return str;
};
至此,一个完整的解码 html 实体符的功能就完成了。
真·一行
利用 innerHTML 和 textContent 来实现。
/**
* 解码 html 实体符
* @param str {String} html 实体符
* @returns {String}
*/
var unescapeHTML = (function (str) {
var $p = document.createElement('p');
$p.style.display = 'none';
document.body.appendChild($p);
return function (str) {
$p.innerHTML = str;
return $p.textContent || $p.innerText;
};
}());
如果原始字符串有 html 标签,则会被过滤。 如
unescapeHTML('<<<<')
// => "<<<<"
unescapeHTML('<<<<<a></a>')
// => "<<<<"
原始的<a>
标签被过滤掉了。
既然 html 标签会被过滤,那么我们可以在开始的时候进行一次 escape 转换即可:
/**
* 解码 html 实体符
* @param str {String} html 实体符
* @returns {String}
*/
var unescapeHTML = (function (str) {
var p = document.createElement('p');
return function (str) {
// 处理掉 < 符号,防止 html 标签(如:<a>)被过滤
p.innerHTML = (str + '').replace(/</g, '<');
return p.textContent || p.innerText || '';
};
}());
</>