2011-02-02 2 views
17

Возможно ли в Javascript определить, содержит ли строка многобайтовые символы? Если да, можно ли сказать, какие из них?Как определить, содержит ли строка многобайтовые символы в Javascript?

Проблема Я бегу в это (извинения, если полукокс Unicode не отображается правильно для вас)

s = ""; 

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

Edit для немного ясности здесь (я надеюсь,).Как я понимаю сейчас,, все строки в Javascript представлены в виде ряда кодовых точек UTF-16, что означает, что обычные символы на самом деле занимают 2 байта (16 бит), поэтому мое использование «multibyte» в заголовке было немного выключено. Некоторые символы не попадают в базовую многоязычную плоскость (BMP), такую ​​как строка в приведенном выше примере, и поэтому они занимают две кодовые точки (32 бита). Это вопрос, который я задавал. Я также не редактирую оригинальное название, так как кому-то, кто мало знает об этом материале (и, следовательно, будет искать SO для информации об этом), «многобайтовый» имеет смысл.

+0

регулярное выражение? – Marco

+0

проверить на что? – nickf

+0

Это для Unicode, или это может быть UTF-8? – Davidann

ответ

23

строки JavaScript являются UCS-2 кодируется, но может представлять Unicode кодовых точек вне Basic Multilingual панели (U+0000 - U+D7FF и U+E000 - U+FFFF) с использованием двух 16-битных чисел (а UTF-16 суррогатной пары), первый из который должен находиться в диапазоне U+D800 - U+DFFF.

Исходя из этого, легко определить, содержит ли строка любые символы, которые лежат вне базовой многоязычной плоскости (что, как я думаю, вы спрашиваете: вы хотите определить, содержит ли строка любые символы, которые лежат вне диапазона кода указывает, что JavaScript представляет как один символ):

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

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

Разработка, какие именно кодовые точки содержатся в строке немного сложнее и требует UTF-16 декодера. Ниже будет преобразовать строку в массив кодовых точек 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

Это моя реализация, чтобы показать больше смайликов, если сообщение не содержит текста

Markup

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

Script

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

Как это ответить на вопрос? – Pac0

Смежные вопросы