2011-02-02 21 views
17

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

El problema que estoy corriendo en es este (disculpas si el carbón Unicode no se presenta a la derecha para usted)

s = ""; 

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

Editar para un poco de claridad aquí (espero).Según 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 realmente ocupan 2 bytes (16 bits), así que mi uso de "multibyte" en el título estaba un poco apagado. Algunos personajes no caen en el plano multilingüe básico (BMP), como la cadena en el 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 sabe mucho sobre esto (y, por lo tanto, estaría buscando SO para obtener información al respecto), "multibyte" tendría sentido.

+0

expresión regular? – Marco

+0

para probar qué? – nickf

+0

¿Esto es para Unicode o también podría ser UTF-8? – Davidann

Respuesta

23

cadenas JavaScript son UCS-2 codificada pero puede representar puntos de código Unicode fuera del panel multilingüe básico (U+0000-U+D7FF y U+E000-U+FFFF) usando dos 16 números de bits (a UTF-16 par suplente), el primero de que debe estar en el rango U+D800 - U+DFFF.

Basado en esto, es fácil detectar si una cadena contiene algún carácter que se encuentre fuera del plano multilingüe básico (que es lo que creo que está preguntando: desea poder identificar si una cadena contiene algún carácter que se encuentran fuera del rango de código JavaScript que señala representa como un solo carácter):

function containsSurrogatePair(str) { 
    return /[\uD800-\uDFFF]/.test(str); 
} 

alert(containsSurrogatePair("foo")); // false 
alert(containsSurrogatePair("f")); // true 

Trabajando con precisión qué puntos de código están contenidos en la cadena es un poco más difícil y requiere un decodificador UTF-16. El siguiente será 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 
0

Ésta es mi aplicación para mostrar emojis más grandes si un mensaje no contiene texto

marcado

<div> 
    <input id="message" placeholder="Nice support for one or multiple emojis"> 
    <button id="post-message">Send</button> 
    <ul id="messages"></ul> 
</div> 

Guión

function jumbotron(str) { 
    return /^[\uD800-\uDFFF]+$/.test(str); 
} 

document.getElementById('post-message').onclick = function() { 
    list_element = document.createElement('li'); 
    message = document.getElementById('message').value; 

    list_element_span = document.createElement('span'); 
    list_element_span.innerHTML = message; 
    list_element.appendChild(list_element_span); 

    if (jumbotron(message)) { 
     list_element_span.style.fontSize = '2em'; 
     list_element_span.style.lineHeight = 'normal'; 
    } 

    document.getElementById('messages').appendChild(list_element) 
} 
+0

¿Cómo responde esto la pregunta? – Pac0

Cuestiones relacionadas