![](/img/trans.png)
[英]How to convert unicode characters to HTML numeric entities using plain Javascript
[英]How to convert characters to HTML entities using plain JavaScript
我有以下幾點:
var text = "Übergroße Äpfel mit Würmern";
我正在尋找一個 Javascript 函數來轉換文本,以便每個特殊字母都由其 HTML 實體序列表示,如下所示:
var newText = magicFunction(text);
...
newText = "Übergroße Äpfel mit Würmern";
你會如何做到這一點? 有沒有現有的功能? (簡單,因為沒有框架的解決方案是首選)
順便說一句:是的,我見過這個問題,但它沒有解決我的需要。
在 bucabay 的幫助和創建我自己的函數的建議下,我創建了這個對我有用的函數。 大家怎么看,有沒有更好的解決方案?
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));
結果:
Übergroße Äpfel mit Würmern
更新 1:再次感謝bucabay的 || - 暗示
更新 2 :使用 amp、lt、gt、apos、quot 更新實體表,感謝richardtallent的提示
Update3(2014 年): Mathias Bynens創建了一個名為 'he' 的庫,也許它可以滿足您的需求。
這里建議的所有其他解決方案,以及大多數其他執行 HTML 實體編碼/解碼的 JavaScript 庫,都會犯一些錯誤:
htmlDecode('≼')
應該返回'≼'
(即'\≼'
)。htmlEncode('𝌆')
應該返回類似𝌆
或𝌆
. 如果一個實現返回兩個單獨的實體(例如��
或��
),它就會被破壞。htmlDecode('𝌆')
應該返回'𝌆'
而不是'팆'
(即'\팆'
)。htmlDecode('€')
應該返回'€'
(即'\€'
)。htmlDecode('&amp;')
應該返回'&'
, 不是&
。對於避免所有這些問題的強大解決方案,請使用我為此編寫的名為he的庫。 從它的自述文件:
he (代表“HTML 實體”)是一個用 JavaScript 編寫的強大的 HTML 實體編碼器/解碼器。 它支持所有標准化的 HTML 命名字符引用, 像瀏覽器一樣處理模糊的&符號和其他邊緣情況,具有廣泛的測試套件,並且——與許多其他 JavaScript 解決方案相反——他可以很好地處理星體 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 字符,那么您可以使用以下內容:
var html = text.replace(/[\u00A0-\u00FF]/g, function(c) {
return '&#'+c.charCodeAt(0)+';';
});
注意這里的范圍是:\ -\ÿ。
這是http://www.w3.org/TR/html4/sgml/entities.html中定義的第一個字符代碼范圍,與 escape() 涵蓋的內容相同。
您還需要添加您想要涵蓋的其他范圍,或所有范圍。
示例:帶有一般標點符號的 UTF-8 范圍(\ -\ÿ 和 \•-\ℵ)
var html = text.replace(/[\u00A0-\u00FF\u2022-\u2135]/g, function(c) {
return '&#'+c.charCodeAt(0)+';';
});
編輯:
順便說一句:\ -\♦ 應該盲目地將不在 ASCII 范圍內的每個 Unicode 字符代碼轉換為 HTML 實體:
var html = text.replace(/[\u00A0-\u2666]/g, function(c) {
return '&#'+c.charCodeAt(0)+';';
});
he庫是我所知道的唯一 100% 可靠的解決方案!
他由世界最著名的 JavaScript 大師之一Mathias Bynens編寫,具有以下特點:
he.encode('foo © bar ≠ baz 𝌆 qux');
// Output : 'foo © bar ≠ baz 𝌆 qux'
he.decode('foo © bar ≠ baz 𝌆 qux');
// Output : 'foo © bar ≠ baz 𝌆 qux'
您可以使用:
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 不是 z/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());
//=> 'Übergroße Äpfel mit Würmern'
擁有一個包含大量 replace() 調用的查找表很慢且不可維護。
幸運的是,內置的escape()函數也對大部分相同的字符進行編碼,並將它們置於一致的格式中(%XX,其中XX 是字符的十六進制值)。
因此,您可以讓 escape() 方法為您完成大部分工作,只需將其答案更改為 HTML 實體而不是 URL 轉義字符:
htmlescaped = escape(mystring).replace(/%(..)/g,"&#x$1;");
這使用十六進制格式來轉義值而不是命名實體,但對於存儲和顯示值,它與命名實體一樣有效。
當然,也逃脫逃脫你不需要在HTML逃脫(空格,例如)字符,但你可以用一些替代的呼叫反轉義它們。
編輯:我比我自己的更喜歡 bucabay 的答案......處理更大范圍的字符,並且之后不需要黑客來獲得空格、斜線等。未轉義。
這是一個很小的獨立方法:
我不太了解 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 "";
});
}
我通過使用encodeURIComponent()
而不是escape()
解決了我的問題。
如果在 URL 中發送字符串時出現問題,這可能是您的解決方法。
試試這個短語 ("hi & % '")
escape()
返回
"hi%20%26%20%25%20%u2018"
請注意%u2018
對 url 不是很友好,可能會破壞查詢字符串的其余部分。
encodeURI()
返回
"hi%20&%20%25%20%E2%80%98"
注意&符號仍然存在。
encodeURIComponent()
返回
"hi%20%26%20%25%20%E2%80%98"
最后,我們所有的字符都被正確編碼。
我建議使用 JS 庫實體。 使用該庫非常簡單。 請參閱文檔中的示例:
const entities = require("entities");
//encoding
entities.escape("&"); // "&#38;"
entities.encodeXML("&"); // "&#38;"
entities.encodeHTML("&"); // "&#38;"
//decoding
entities.decodeXML("asdf & ÿ ü '"); // "asdf & ÿ ü '"
entities.decodeHTML("asdf & ÿ ü '"); // "asdf & ÿ ü '"
最佳解決方案發布在 phpjs.org implementation of PHP function htmlentities
格式是htmlentities(string, quote_style, charset, double_encode)
關於 PHP 函數的完整文檔可以在這里閱讀
我改編了參考問題的答案之一,但添加了為字符名稱定義顯式映射的功能。
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));
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.