如何使用普通的JavaScript将字符转换为HTML实体

我有以下几点:

var text = "Übergroße Äpfel mit Würmern"; 

我正在寻找一个Javascript函数来转换文本,以便每个特殊的字母都是用它的HTML实体序列表示的:

 var newText = magicFunction(text); ... newText = "Übergroße Äpfel mit Würmern"; 

这个函数不仅可以逃避这个例子的字母, 而且还可以逃避所有这些。

你将如何实现? 那里是否有任何现有的function? (普通的,因为没有框架的解决scheme是首选)

顺便说一句:是的,我已经看到了这个问题,但没有解决我的需要。

在bucabay的帮助和build立我自己的function的build议,我创造了这个为我工作。 你们觉得呢,有什么更好的解决scheme吗?

 if(typeof escapeHtmlEntities == 'undefined') { escapeHtmlEntities = function (text) { return text.replace(/[\u00A0-\u2666<>\&]/g, function(c) { return '&' + (escapeHtmlEntities.entityTable[c.charCodeAt(0)] || '#'+c.charCodeAt(0)) + ';'; }); }; // all HTML4 entities as defined here: http://www.w3.org/TR/html4/sgml/entities.html // added: amp, lt, gt, quot and apos escapeHtmlEntities.entityTable = { 34 : 'quot', 38 : 'amp', 39 : 'apos', 60 : 'lt', 62 : 'gt', 160 : 'nbsp', 161 : 'iexcl', 162 : 'cent', 163 : 'pound', 164 : 'curren', 165 : 'yen', 166 : 'brvbar', 167 : 'sect', 168 : 'uml', 169 : 'copy', 170 : 'ordf', 171 : 'laquo', 172 : 'not', 173 : 'shy', 174 : 'reg', 175 : 'macr', 176 : 'deg', 177 : 'plusmn', 178 : 'sup2', 179 : 'sup3', 180 : 'acute', 181 : 'micro', 182 : 'para', 183 : 'middot', 184 : 'cedil', 185 : 'sup1', 186 : 'ordm', 187 : 'raquo', 188 : 'frac14', 189 : 'frac12', 190 : 'frac34', 191 : 'iquest', 192 : 'Agrave', 193 : 'Aacute', 194 : 'Acirc', 195 : 'Atilde', 196 : 'Auml', 197 : 'Aring', 198 : 'AElig', 199 : 'Ccedil', 200 : 'Egrave', 201 : 'Eacute', 202 : 'Ecirc', 203 : 'Euml', 204 : 'Igrave', 205 : 'Iacute', 206 : 'Icirc', 207 : 'Iuml', 208 : 'ETH', 209 : 'Ntilde', 210 : 'Ograve', 211 : 'Oacute', 212 : 'Ocirc', 213 : 'Otilde', 214 : 'Ouml', 215 : 'times', 216 : 'Oslash', 217 : 'Ugrave', 218 : 'Uacute', 219 : 'Ucirc', 220 : 'Uuml', 221 : 'Yacute', 222 : 'THORN', 223 : 'szlig', 224 : 'agrave', 225 : 'aacute', 226 : 'acirc', 227 : 'atilde', 228 : 'auml', 229 : 'aring', 230 : 'aelig', 231 : 'ccedil', 232 : 'egrave', 233 : 'eacute', 234 : 'ecirc', 235 : 'euml', 236 : 'igrave', 237 : 'iacute', 238 : 'icirc', 239 : 'iuml', 240 : 'eth', 241 : 'ntilde', 242 : 'ograve', 243 : 'oacute', 244 : 'ocirc', 245 : 'otilde', 246 : 'ouml', 247 : 'divide', 248 : 'oslash', 249 : 'ugrave', 250 : 'uacute', 251 : 'ucirc', 252 : 'uuml', 253 : 'yacute', 254 : 'thorn', 255 : 'yuml', 402 : 'fnof', 913 : 'Alpha', 914 : 'Beta', 915 : 'Gamma', 916 : 'Delta', 917 : 'Epsilon', 918 : 'Zeta', 919 : 'Eta', 920 : 'Theta', 921 : 'Iota', 922 : 'Kappa', 923 : 'Lambda', 924 : 'Mu', 925 : 'Nu', 926 : 'Xi', 927 : 'Omicron', 928 : 'Pi', 929 : 'Rho', 931 : 'Sigma', 932 : 'Tau', 933 : 'Upsilon', 934 : 'Phi', 935 : 'Chi', 936 : 'Psi', 937 : 'Omega', 945 : 'alpha', 946 : 'beta', 947 : 'gamma', 948 : 'delta', 949 : 'epsilon', 950 : 'zeta', 951 : 'eta', 952 : 'theta', 953 : 'iota', 954 : 'kappa', 955 : 'lambda', 956 : 'mu', 957 : 'nu', 958 : 'xi', 959 : 'omicron', 960 : 'pi', 961 : 'rho', 962 : 'sigmaf', 963 : 'sigma', 964 : 'tau', 965 : 'upsilon', 966 : 'phi', 967 : 'chi', 968 : 'psi', 969 : 'omega', 977 : 'thetasym', 978 : 'upsih', 982 : 'piv', 8226 : 'bull', 8230 : 'hellip', 8242 : 'prime', 8243 : 'Prime', 8254 : 'oline', 8260 : 'frasl', 8472 : 'weierp', 8465 : 'image', 8476 : 'real', 8482 : 'trade', 8501 : 'alefsym', 8592 : 'larr', 8593 : 'uarr', 8594 : 'rarr', 8595 : 'darr', 8596 : 'harr', 8629 : 'crarr', 8656 : 'lArr', 8657 : 'uArr', 8658 : 'rArr', 8659 : 'dArr', 8660 : 'hArr', 8704 : 'forall', 8706 : 'part', 8707 : 'exist', 8709 : 'empty', 8711 : 'nabla', 8712 : 'isin', 8713 : 'notin', 8715 : 'ni', 8719 : 'prod', 8721 : 'sum', 8722 : 'minus', 8727 : 'lowast', 8730 : 'radic', 8733 : 'prop', 8734 : 'infin', 8736 : 'ang', 8743 : 'and', 8744 : 'or', 8745 : 'cap', 8746 : 'cup', 8747 : 'int', 8756 : 'there4', 8764 : 'sim', 8773 : 'cong', 8776 : 'asymp', 8800 : 'ne', 8801 : 'equiv', 8804 : 'le', 8805 : 'ge', 8834 : 'sub', 8835 : 'sup', 8836 : 'nsub', 8838 : 'sube', 8839 : 'supe', 8853 : 'oplus', 8855 : 'otimes', 8869 : 'perp', 8901 : 'sdot', 8968 : 'lceil', 8969 : 'rceil', 8970 : 'lfloor', 8971 : 'rfloor', 9001 : 'lang', 9002 : 'rang', 9674 : 'loz', 9824 : 'spades', 9827 : 'clubs', 9829 : 'hearts', 9830 : 'diams', 338 : 'OElig', 339 : 'oelig', 352 : 'Scaron', 353 : 'scaron', 376 : 'Yuml', 710 : 'circ', 732 : 'tilde', 8194 : 'ensp', 8195 : 'emsp', 8201 : 'thinsp', 8204 : 'zwnj', 8205 : 'zwj', 8206 : 'lrm', 8207 : 'rlm', 8211 : 'ndash', 8212 : 'mdash', 8216 : 'lsquo', 8217 : 'rsquo', 8218 : 'sbquo', 8220 : 'ldquo', 8221 : 'rdquo', 8222 : 'bdquo', 8224 : 'dagger', 8225 : 'Dagger', 8240 : 'permil', 8249 : 'lsaquo', 8250 : 'rsaquo', 8364 : 'euro' }; } 

用法示例:

 var text = "Übergroße Äpfel mit Würmern"; alert(escapeHtmlEntities (text)); 

结果:

 &Uuml;bergro&szlig;e &Auml;pfel mit W&uuml;rmern 
  • 更新1:再次感谢bucabay的|| – 提示

  • Update2:用amp,lt,gt,apos,quot更新了实体表,感谢richardtallent提示

  • Update3(2014年): Mathias Bynens创build了一个名为“他”的库 ,也许它符合你的需要。

这里提出的所有其他解决scheme,以及其他大多数执行HTML实体编码/解码的JavaScript库,都会犯下几个错误:

  • 他们没有实现浏览器支持的命名字符引用的完整列表 。 例如, htmlDecode('&PrecedesSlantEqual;')应该返回'≼' ( 即'\u227C' )。
  • 他们不支持正确编码星体符号。 例如, htmlEncode('𝌆')应该返回类似于&#x1D306; 或者&#119558; 。 如果一个实现返回两个单独的实体(例如&#xD834;&#xDF06;&#55348;&#57094; ),则会被破坏。
  • 他们不支持正确解码星体符号。 htmlDecode('&#x1D306;')应该返回'𝌆'而不是'팆' ( 即'\uD306' )。
  • 它们不实现HTML标准中列出的字符引用覆盖表 。 例如, htmlDecode('&#x80;')应该返回'€' ( 即'\u20AC' )。
  • 他们应该一次执行解码。 例如, htmlDecode('&#x26;amp;')应该返回'&amp;' ,而不是。

为了避免所有这些问题的健壮的解决scheme,请使用他的库 。 从它的README:

(用于“HTML实体”)是用JavaScript编写的健壮的HTML实体编码器/解码器。 它支持所有按照HTML标准化的命名字符引用 , 像浏览器一样处理不明确的&符号和其他边界情况,具有广泛的testing套件,与许多其他JavaScript解决scheme相反, 处理的是星体Unicode符号。 在线演示可用。

使用escape()应该使用字符代码范围0x00到0xFF( UTF-8范围 )。

如果超出0xFF(255),如0x100(256),则escape()将不起作用:

 escape("\u0100"); // %u0100 

和:

 text = "\u0100"; // Ā html = escape(text).replace(/%(..)/g,"&#x$1;"); // &#xu0;100 

所以,如果你想覆盖http://www.w3.org/TR/html4/sgml/entities.html中定义的所有Unicode charachacter,那么你可以使用类似于:

 var html = text.replace(/[\u00A0-\u00FF]/g, function(c) { return '&#'+c.charCodeAt(0)+';'; }); 

请注意,范围介于:\ u00A0- \ u00FF之间。

这是http://www.w3.org/TR/html4/sgml/entities.html中定义的第一个字符代码范围,它与escape()涵盖的范围相同。;

您需要添加您想要覆盖的其他范围,或者全部。

例如 :带有一般标点符号的UTF-8范围(\ u00A0- \ u00FF和\ u2022- \ u2135)

 var html = text.replace(/[\u00A0-\u00FF\u2022-\u2135]/g, function(c) { return '&#'+c.charCodeAt(0)+';'; }); 

编辑:

BTW:\ u00A0- \ u2666应该将不在ASCII范围内的每个Unicode字符代码盲目地转换为HTML实体:

 var html = text.replace(/[\u00A0-\u2666]/g, function(c) { return '&#'+c.charCodeAt(0)+';'; }); 

您可以使用:

 function encodeHTML(str){ var aStr = str.split(''), i = aStr.length, aRet = []; while (i--) { var iC = aStr[i].charCodeAt(); if (iC < 65 || iC > 127 || (iC>90 && iC<97)) { aRet.push('&#'+iC+';'); } else { aRet.push(aStr[i]); } } return aRet.reverse().join(''); } 

这个函数HTMLEncodes不是所有的az / AZ。

[ 编辑 ]一个相当古老的答案。 让我们添加一个更简单的string扩展来编码所有扩展字符:

 String.prototype.encodeHTML = function () { return this.replace(/[\u0080-\u024F]/g, function (v) {return '&#'+v.charCodeAt()+';';} ); } // usage log('Übergroße Äpfel mit Würmern'.encodeHTML()); //=> '&#220;bergro&#223;e &#196;pfel mit W&#252;rmern' 

有一个bazillionreplace()调用的查找表是慢和不可维护的。

幸运的是,内build的escape()函数也对大部分相同的字符进行编码,并将它们以一致的格式(%XX,其中XX是字符的hex值)进行编码。

所以,你可以让escape()方法为你做大部分的工作,只是把它的答案改成HTML实体而不是URL转义的字符:

 htmlescaped = escape(mystring).replace(/%(..)/g,"&#x$1;"); 

这使用hex格式来转义值而不是命名实体,但是为了存储和显示值,它和命名实体一样工作。

当然,逃生也逃脱了你不需要用HTML(空格)转义的字符,但是你可以用几个replace的调用避开它们。

编辑:我喜欢bucabay的回答比我自己的更好…处理更大范围的angular色,并且不需要黑客之后得到空间,斜杠等未经转义。

在JSFiddle上演示

这里有一个小小的独立方法:

  • 尝试在本页面上整理答案,而不使用库
  • 在较旧的浏览器中工作
  • 支持代理对(如emojis)
  • 应用字符覆盖(这是什么?不完全确定)

我不太了解unicode,但它似乎运作良好。

 // escape a string for display in html // see also: // polyfill for String.prototype.codePointAt // https://raw.githubusercontent.com/mathiasbynens/String.prototype.codePointAt/master/codepointat.js // how to convert characters to html entities // http://stackoverflow.com/a/1354491/347508 // html overrides from // https://html.spec.whatwg.org/multipage/syntax.html#table-charref-overrides / http://stackoverflow.com/questions/1354064/how-to-convert-characters-to-html-entities-using-plain-javascript/23831239#comment36668052_1354098 var _escape_overrides = { 0x00:'\uFFFD',0x80:'\u20AC',0x82:'\u201A',0x83:'\u0192',0x84:'\u201E',0x85:'\u2026',0x86:'\u2020',0x87:'\u2021',0x88:'\u02C6',0x89:'\u2030',0x8A:'\u0160',0x8B:'\u2039',0x8C:'\u0152',0x8E:'\u017D',0x91:'\u2018',0x92:'\u2019',0x93:'\u201C',0x94:'\u201D',0x95:'\u2022',0x96:'\u2013',0x97:'\u2014',0x98:'\u02DC',0x99:'\u2122',0x9A:'\u0161',0x9B:'\u203A',0x9C:'\u0153',0x9E:'\u017E',0x9F:'\u0178' }; function escapeHtml(str){ return str.replace(/([\u0000-\uD799]|[\uD800-\uDBFF][\uDC00-\uFFFF])/g, function(c) { var c1 = c.charCodeAt(0); // ascii character, use override or escape if( c1 <= 0xFF ) return (c1=_escape_overrides[c1])?c1:escape(c).replace(/%(..)/g,"&#x$1;"); // utf8/16 character else if( c.length == 1 ) return "&#" + c1 + ";"; // surrogate pair else if( c.length == 2 && c1 >= 0xD800 && c1 <= 0xDBFF ) return "&#" + ((c1-0xD800)*0x400 + c.charCodeAt(1) - 0xDC00 + 0x10000) + ";" // no clue .. else return ""; }); } 

他的图书馆是我所知道的唯一100%可靠的解决scheme!

由世界上最着名的JavaScript大师之一Mathias Bynens编写,具有以下特点:

  • 支持所有标准化的命名字符引用
  • 支持unicode
  • 适用于模糊的&符号

使用示例

 he.encode('foo © bar ≠ baz 𝌆 qux'); // Output : 'foo &#xA9; bar &#x2260; baz &#x1D306; qux' he.decode('foo &copy; bar &ne; baz &#x1D306; qux'); // Output : 'foo © bar ≠ baz 𝌆 qux' 

只需将@ bucababy的答案转换为“小书签”,因为它有时比使用这些 查找页面更容易:

 alert(prompt('Enter characters to htmlEncode', '').replace(/[\u00A0-\u2666]/g, function(c) { return '&#'+c.charCodeAt(0)+';'; })); 

最好的解决办法是张贴在phpjs.org实现PHP函数htmlentities

格式是htmlentities(string, quote_style, charset, double_encode)完整的PHP函数相关的文档可以在这里阅读

我通过使用 encodeURIComponent() 而不是 escape() 解决我的问题

如果在URL中发送string时发生问题,这可能是您的问题。

试试这个短语(“嗨&%'”)

escape()返回

 "hi%20%26%20%25%20%u2018" 

请注意, %u2018不是非常友好的url,可以打破查询string的其余部分。

encodeURI()返回

 "hi%20&%20%25%20%E2%80%98" 

注意&符号仍然存在。

encodeURIComponent()返回

 "hi%20%26%20%25%20%E2%80%98" 

最后,我们所有的angular色都被正确编码了。

我修改了引用问题的答案之一,但增加了为字符名称定义显式映射的function。

 var char_names = { 160:'nbsp', 161:'iexcl', 220:'Uuml', 223:'szlig', 196:'Auml', 252:'uuml', }; function HTMLEncode(str){ var aStr = str.split(''), i = aStr.length, aRet = []; while (--i >= 0) { var iC = aStr[i].charCodeAt(); if (iC < 32 || (iC > 32 && iC < 65) || iC > 127 || (iC>90 && iC<97)) { if(char_names[iC]!=undefined) { aRet.push('&'+char_names[iC]+';'); } else { aRet.push('&#'+iC+';'); } } else { aRet.push(aStr[i]); } } return aRet.reverse().join(''); } var text = "Übergroße Äpfel mit Würmer"; alert(HTMLEncode(text));