2010-11-27 9 views
5

Ich versuche, JavaScript & regex zu verwenden, um numerische HTML-Entitäten durch ihre tatsächlichen Unicode-Zeichen zu ersetzen, z.Verwenden Sie JavaScript-Regex, um numerische HTML-Entitäten durch ihre tatsächlichen Zeichen zu ersetzen

foo's bar 
→ 
foo's bar 

Das ist, was ich bisher habe:

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

, das zu tun ist alles links ist die Zahl mit String.fromCharCode($1) zu ersetzen, aber ich kann nicht scheinen, um es zu bekommen zu arbeiten. Wie kann ich das machen?

Antwort

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

Das gibt nur "foos bar" 'zurück. Fehle ich etwas? Edit: Oh, anscheinend, weil 'match' =' "'" 'und nicht nur die' 39'. – alfonso

+0

ja du bist richtig, ich reparierte den Code seitdem –

+0

Danke, das funktioniert! Ich akzeptiere deine Antwort in 5 Minuten. – alfonso

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

Erstes Argument (x) ist ein "'" im aktuellen Beispiel. y ist 39.

0

Wenn Sie nicht alle Entitäten definieren möchten, können Sie den Browser das für Sie tun lassen - dieses Bit erzeugt ein leeres p-Element, schreibt den HTML-Code und gibt den erzeugten Text zurück. Das Element p wird dem Dokument nie hinzugefügt.

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

Bitte tun Sie das nicht. Der integrierte HTML-Parser hat viel zu viel Autorität, um beliebigen Inhalten zu vertrauen. Dies wartet nur darauf, dass XSS passiert. Obwohl Skriptelemente nicht als Ergebnis von 'innerHTML' ausgeführt werden, ist dies nur ein Vektor. Es gibt viele andere (CSS 'expression',' onerror'-Handler, Objekt- und Einbettungselemente, eingebettete XML- und externe Entitäten), um einige zu nennen, die Codeausführung oder beliebige Netzwerkanforderungen ermöglichen können. –

3

Neben einer Callback-Funktion verwenden, können Sie das Hinzufügen der Unterstützung für hex Zeichenreferenzen berücksichtigen wollen (ሴ).

Auch fromCharCode kann nicht genug sein. Beispiel: 𐤀 ist ein gültiger Verweis auf ein phönizisches Zeichen, aber da es sich außerhalb der Basic Multilingual Plane befindet und das String-Modell von JavaScript auf UTF-16-Codeeinheiten basiert, werden keine vollständigen Zeichencodepunkte verwendet. fromCharCode(67840) funktioniert nicht. Sie benötigen einen UTF-16-Encoder, zum Beispiel:

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;!')); 
Verwandte Themen