2010-11-27 30 views
5

Estoy tratando de usar JavaScript & regex para reemplazar entidades HTML numéricas con sus caracteres Unicode reales, p. Ej.Usar JavaScript regex para reemplazar entidades HTML numéricas con sus caracteres reales

foo's bar 
→ 
foo's bar 

Esto es lo que tengo hasta ahora:

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

Todo lo que queda por hacer es sustituir el número String.fromCharCode($1), pero me parece que no puede conseguir que funcione. ¿Cómo puedo hacer esto?

Respuesta

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

Eso simplemente devuelve '" foos bar "'. ¿Me estoy perdiendo de algo? Edit: Oh, aparentemente eso es porque 'match' =' "'" 'y no solo el' 39'. – alfonso

+0

sí, estás en lo correcto, he corregido el código desde entonces –

+0

¡Gracias, eso funciona! Aceptaré tu respuesta en 5 minutos. – alfonso

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

primer argumento (x) es un "'" en el ejemplo actual. y es 39.

0

Si no quiere definir todas las entidades, puede dejar que el navegador lo haga por usted; este bit crea un elemento p vacío, escribe el html y devuelve el texto que produce. El elemento p nunca se agrega al documento.

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

Por favor, no hagas esto. El analizador de HTML incorporado tiene demasiada autoridad para confiar en el contenido arbitrario. Esto solo está esperando a que ocurra XSS. Aunque los elementos del guión no se ejecutan como resultado de la configuración de 'innerHTML', eso es solo un vector. Existen muchos otros (gestores de '' expresión '', '' onerror', elementos de objetos e incrustaciones, entidades embebidas XML y externas) para nombrar algunos que podrían causar la ejecución de código o permitir solicitudes de red arbitrarias. –

3

Además de utilizar una función de devolución de llamada, es posible que desee considerar la adición de soporte para las referencias de carácter hexadecimal (ሴ).

Además, fromCharCode puede que no sea suficiente. por ejemplo, 𐤀 es una referencia válida para un personaje fenicio, pero como está fuera del plano multilingüe básico y el modelo de cadena de JavaScript se basa en unidades de código UTF-16, no completan los puntos de código de carácter, fromCharCode(67840) no funcionará. Necesitaría un codificador UTF-16, por ejemplo:

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;!')); 
Cuestiones relacionadas