javascript string internationalization multibyte

title html javascript



¿Cómo puedo saber si una cadena contiene caracteres multibyte en Javascript? (1)

¿Es posible en Javascript detectar si una cadena contiene caracteres multibyte? Si es así, ¿es posible decir cuáles?

El problema que estoy encontrando es este (disculpas si el personaje de Unicode no se muestra bien para ti)

s = "𝌆"; alert(s.length); // ''2'' alert(s.charAt(0)); // ''��'' alert(s.charAt(1)); // ''��''

Editar para un poco de claridad aquí (espero) . Como lo entiendo ahora , todas las cadenas en Javascript están representadas como una serie de puntos de código UTF-16, lo que significa que los caracteres regulares ocupan 2 bytes (16 bits), por lo que mi uso de "multibyte" en el título fue un poco apagado. Algunos caracteres no se incluyen en el Plano Multilingüe Básico (BMP), como la cadena del ejemplo anterior, por lo que ocupan dos puntos de código (32 bits). Esa es la pregunta que estaba haciendo. Tampoco estoy editando el título original, ya que para alguien que no sepa mucho sobre esto (y, por lo tanto, estaría buscando SU información), "multibyte" tendría sentido.


Las cadenas de JavaScript están codificadas en UCS-2 pero pueden representar puntos de código Unicode fuera del Panel Multilingüe Básico ( U+0000 - U+D7FF y U+E000 - U+FFFF ) usando dos números de 16 bits (un par suplente UTF-16), el El primero de los cuales debe estar en el rango U+D800 - U+DFFF .

En base a esto, es fácil detectar si una cadena contiene caracteres que se encuentran fuera del Plano Multilingüe Básico (que es lo que creo que estás preguntando: quieres poder identificar si una cadena contiene caracteres que están fuera del rango) de puntos de código que JavaScript representa como un solo carácter):

function containsSurrogatePair(str) { return /[/uD800-/uDFFF]/.test(str); } alert( containsSurrogatePair("foo") ); // false alert( containsSurrogatePair("f𝌆") ); // true

Resolver con precisión qué puntos de código están contenidos en su cadena es un poco más difícil y requiere un decodificador UTF-16. Lo siguiente convertirá una cadena en una matriz de puntos de código Unicode:

var getStringCodePoints = (function() { function surrogatePairToCodePoint(charCode1, charCode2) { return ((charCode1 & 0x3FF) << 10) + (charCode2 & 0x3FF) + 0x10000; } // Read string in character by character and create an array of code points return function(str) { var codePoints = [], i = 0, charCode; while (i < str.length) { charCode = str.charCodeAt(i); if ((charCode & 0xF800) == 0xD800) { codePoints.push(surrogatePairToCodePoint(charCode, str.charCodeAt(++i))); } else { codePoints.push(charCode); } ++i; } return codePoints; } })(); alert( getStringCodePoints("f𝌆").join(",") ); // 102,119558