2010-11-27 36 views
5

J'essaie d'utiliser JavaScript & regex pour remplacer les entités HTML numériques avec leurs caractères Unicode réels, par exemple.Utilisez regex JavaScript pour remplacer les entités HTML numériques avec leurs caractères réels

foo's bar 
→ 
foo's bar 

C'est ce que je suis arrivé à ce jour:

"foo's bar".replace(/&#([^\s]*);/g, "$1"); // "foo39s bar" 

Tout ce qui reste à faire est de remplacer le numéro avec String.fromCharCode($1), mais je ne peux pas sembler le faire fonctionner. Comment puis-je faire ceci?

Répondre

8
"foo's bar".replace(/&#(\d+);/g, function(match, match2) {return String.fromCharCode(+match2);}) 
+0

Cela renvoie juste '' 'foos bar'' '. Est-ce que je manque quelque chose? Edit: Oh, apparemment, c'est parce que 'match' =" ' "' et pas seulement le '39'. – alfonso

+0

oui vous avez raison, j'ai corrigé le code depuis –

+0

Merci, ça marche! Je vais accepter votre réponse dans 5 minutes. – alfonso

3
"foo's bar".replace(/&#([^\s]*);/g, function(x, y) { return String.fromCharCode(y) }) 

Le premier argument (x) est un "'" dans l'exemple actuel. y est 39.

0

Si vous ne voulez pas définir toutes les entités, vous pouvez laisser le navigateur le faire pour vous - ce bit crée un élément p vide, écrit le code HTML et renvoie le texte qu'il produit. L'élément p n'est jamais ajouté au document.

function translateEntities(string){ 
    var text, p=document.createElement('p'); 
    p.innerHTML=string; 
    text= p.innerText || p.textContent; 
    p.innerHTML=''; 
    return text; 
} 
var s= 'foo's bar'; 
translateEntities(s); 

/* returned value: (String) 
foo's bar 
*/ 
+0

S'il vous plaît ne pas le faire. L'analyseur HTML intégré a beaucoup trop d'autorité pour faire confiance à du contenu arbitraire. Ceci n'attend que XSS. Même si les éléments de script ne sont pas exécutés à la suite de la définition de 'innerHTML', ce n'est qu'un vecteur. Il y en a beaucoup d'autres (les gestionnaires CSS 'expression',' onerror', les éléments d'objet et d'embed, les XML embarqués et les entités externes) pour en nommer quelques-uns qui pourraient provoquer l'exécution de code ou autoriser des requêtes réseau arbitraires. –

3

En plus d'utiliser une fonction de rappel, vous pouvez envisager d'ajouter le support pour les références de caractère hexagonal (ሴ).

En outre,peut ne pas suffire. Par exemple 𐤀 est une référence valide à un caractère phénicien, mais parce qu'il est en dehors du plan multilingue de base et que le modèle String de JavaScript est basé sur des unités de code UTF-16, pas de code complet, fromCharCode(67840) ne fonctionnera pas. Vous auriez besoin d'un encodeur UTF-16, par exemple:

String.fromCharCodePoint= function(/* codepoints */) { 
    var codeunits= []; 
    for (var i= 0; i<arguments.length; i++) { 
     var c= arguments[i]; 
     if (arguments[i]<0x10000) { 
      codeunits.push(arguments[i]); 
     } else if (arguments[i]<0x110000) { 
      c-= 0x10000; 
      codeunits.push((c>>10 & 0x3FF) + 0xD800); 
      codeunits.push((c&0x3FF) + 0xDC00); 
     } 
    } 
    return String.fromCharCode.apply(String, codeunits); 
}; 

function decodeCharacterReferences(s) { 
    return s.replace(/&#(\d+);/g, function(_, n) {; 
     return String.fromCharCodePoint(parseInt(n, 10)); 
    }).replace(/&#x([0-9a-f]+);/gi, function(_, n) { 
     return String.fromCharCodePoint(parseInt(n, 16)); 
    }); 
}; 

alert(decodeCharacterReferences('Hello &#x10900; mum &#67840;!'));