web-dev-qa-db-fra.com

Comment convertir des caractères en entités HTML à l'aide de JavaScript simple

J'ai les éléments suivants:

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

Je recherche une fonction Javascript pour transformer le texte afin que chaque lettre spéciale soit représentée par sa séquence d'entités HTML comme ceci:

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

La fonction devrait non seulement échapper aux lettres de cet exemple mais aussi à toutes celles-ci.

Comment y arriveriez-vous? Existe-t-il une fonction existante? (Simple, car une solution sans cadre est préférable)

Btw: Oui, j'ai vu cette question mais ça ne répond pas à mon besoin.

53
Chris

Avec l'aide de bucabay et les conseils pour créer ma propre fonction, j'ai créé celle-ci qui fonctionne pour moi. Qu'en pensez-vous, y a-t-il une meilleure solution quelque part?

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'
        };
    }

exemple d'utilisation:

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

résultat:

&Uuml;bergro&szlig;e &Auml;pfel mit W&uuml;rmern
61
Chris

Toutes les autres solutions suggérées ici, ainsi que la plupart des autres bibliothèques JavaScript qui effectuent l'encodage/décodage d'entités HTML, font plusieurs erreurs:

Pour une solution robuste qui évite tous ces problèmes, utilisez la bibliothèque he pour cela. De son README:

he (pour les "entités HTML") est un encodeur/décodeur d'entité HTML robuste écrit en JavaScript. Il prend en charge toutes les références de caractères nommées normalisées selon HTML , gère esperluettes ambiguës et d'autres cas Edge tout comme le ferait un navigateur , a une suite de tests complète , et - contrairement à de nombreuses autres solutions JavaScript - he gère très bien les symboles astral Unicode. ne démo en ligne est disponible.

48
Mathias Bynens

L'utilisation de escape () devrait fonctionner avec la plage de codes de caractères 0x00 à 0xFF ( plage UTF-8 ).

Si vous allez au-delà de 0xFF (255), tel que 0x100 (256), alors escape () ne fonctionnera pas:

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

et:

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

Donc, si vous souhaitez couvrir tous les caractères Unicode tels que définis sur http://www.w3.org/TR/html4/sgml/entities.html , vous pouvez utiliser quelque chose comme:

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

Notez ici que la plage est comprise entre:\u00A0-\u00FF.

C'est la première plage de codes de caractères définie dans http://www.w3.org/TR/html4/sgml/entities.html qui est identique à ce que couvre escape ().

Vous devrez également ajouter les autres gammes que vous souhaitez couvrir, ou toutes.

Exemple : plage UTF-8 avec ponctuations générales (\ u00A0-\u00FF et\u2022-\u2135)

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

Modifier:

BTW:\u00A0-\u2666 doit convertir aveuglément tous les codes de caractères Unicode non compris dans la plage ASCII en entités HTML:

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

La bibliothèque he est la seule solution 100% fiable que je connaisse!

He est écrit par Mathias Bynens - l'un des gourous JavaScript les plus renommés au monde - et présente les caractéristiques suivantes:


Exemple d'utilisation

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'
7
John Slegers

Vous pouvez utiliser:

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('');
}

Cette fonction HTMLEcode tout ce qui n'est pas a-z/A-Z.

[ Modifier ] Une réponse assez ancienne. Ajoutons une extension de chaîne plus simple pour encoder tous les caractères étendus:

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'
6
KooiInc

Avoir une table de recherche avec un appel bazillion replace () est lent et non maintenable.

Heureusement, la fonction intégrée escape () également code la plupart des mêmes caractères et les met dans un format cohérent (% XX, où XX est la valeur hexadécimale du caractère).

Ainsi, vous pouvez laisser la méthode escape () faire la plupart du travail pour vous et changer simplement sa réponse en entités HTML au lieu de caractères d'échappement URL:

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

Cela utilise le format hexadécimal pour échapper des valeurs plutôt que les entités nommées, mais pour stocker et afficher les valeurs, cela fonctionne aussi bien que les entités nommées.

Bien sûr, échapper échappe également aux caractères que vous n'avez pas besoin de échapper en HTML (espaces, par exemple), mais vous pouvez les échapper avec quelques appels de remplacement.

Edit: J'aime la réponse de bucabay mieux que la mienne ... gère un plus grand nombre de caractères, et ne nécessite aucun piratage par la suite pour obtenir des espaces, des barres obliques, etc. sans échapper.

4
richardtallent

Démo sur JSFiddle

voici une toute petite méthode autonome qui:

  • tente de consolider les réponses sur cette page, sans utiliser de bibliothèque
  • fonctionne dans les anciens navigateurs
  • prend en charge les paires de substitution (comme les emojis)
  • applique des remplacements de caractères (qu'est-ce que c'est? Je ne sais pas exactement)

je ne sais pas trop sur l'unicode, mais il semble bien fonctionner.

// 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 "";
    });
}
3
kritzikratzi

J'ai résolu mon problème en utilisantencodeURIComponent()au lieu deescape().

Cela pourrait être la solution pour vous si le problème se produit lors de l'envoi de votre chaîne dans une URL.

Essayez ceci avec la phrase ("salut &%‘ ")

escape() renvoie

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

Notez que %u2018 N'est pas très convivial pour les URL et peut casser le reste de la chaîne de requête.

encodeURI() renvoie

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

Remarquez que l'esperluette est toujours là.

encodeURIComponent() renvoie

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

Enfin, tous nos personnages sont correctement encodés.

1
Adam Grant

Il suffit de republier @ bucababy's answer en tant que "bookmarklet", car c'est parfois plus facile que d'utiliser ceux-cirecherche pages:

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

Je recommande d'utiliser la bibliothèque JS entités . L'utilisation de la bibliothèque est assez simple. Voir les exemples de documents:

const entities = require("entities");
//encoding
entities.escape("&#38;"); // "&#x26;#38;"
entities.encodeXML("&#38;"); // "&amp;#38;"
entities.encodeHTML("&#38;"); // "&amp;&num;38&semi;"
//decoding
entities.decodeXML("asdf &amp; &#xFF; &#xFC; &apos;"); // "asdf & ÿ ü '"
entities.decodeHTML("asdf &amp; &yuml; &uuml; &apos;"); // "asdf & ÿ ü '"
0
Antonín Slejška

La meilleure solution est publiée sur l'implémentation phpjs.org de PHP - htmlentities

Le format est htmlentities(string, quote_style, charset, double_encode) Une documentation complète sur la PHP fonction identique peut être lue ici

0
Ronny Sherer