2011-02-02 19 views
17

Czy w języku JavaScript można wykryć, czy ciąg zawiera znaki wielobajtowe? Jeśli tak, to czy można powiedzieć, które z nich?Jak mogę sprawdzić, czy ciąg zawiera znaki wielobajtowe w JavaScript?

Problem używam do jest to (przepraszam jeśli char Unicode nie pojawi się dla ciebie)

s = ""; 

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

Edycja na trochę jasności tutaj (mam nadzieję,).Jak rozumiem teraz:, wszystkie ciągi w Javascriptu są reprezentowane jako seria punktów kodowych UTF-16, co oznacza, że ​​zwykłe postacie zajmują obecnie 2 bajty (16 bitów), więc moje użycie "wielobajtowego" w tytule było trochę nie tak. Niektóre znaki nie mieszczą się w podstawowej płaszczyźnie wielojęzycznej (BMP), takiej jak łańcuch w powyższym przykładzie, a więc zajmują dwa punkty kodowe (32 bity). To jest pytanie, które zadaję. Nie edytuję też oryginalnego tytułu, ponieważ dla kogoś, kto nie ma zbyt wiele informacji na ten temat (i dlatego szukałby SO w celu uzyskania informacji na jego temat), "multibajt" miałby sens.

+0

wyrażenie regularne? – Marco

+0

do sprawdzenia czego? – nickf

+0

Czy jest to dla Unicode, czy też może być również UTF-8? – Davidann

Odpowiedz

23

ciągi JavaScript jest UCS-2 kodowany ale może reprezentować Unicode punkty kodowe poza Basic Multilingual Pane (U+0000 - U+D7FF i U+E000 - U+FFFF) za pomocą dwóch 16 numerów bitowe (UTF-16 surogat para), pierwszy który musi znajdować się w zakresie U+D800 - U+DFFF.

Na tej podstawie można łatwo stwierdzić, czy ciąg znaków zawiera znaki leżące poza Podstawową płaszczyzną wielojęzyczną (o to myślę, że pytasz: chcesz móc określić, czy ciąg znaków zawiera dowolne znaki, leżą poza zakresem kod wskazuje, że JavaScript reprezentuje jako pojedynczego znaku):

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

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

Wypracowanie dokładnie punkty kodowe, które są zawarte w ciąg jest trochę trudniejsze i wymaga UTF-16 dekodera. Następujące będzie przekonwertować ciąg na tablicę Unicode punktów kod:

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

To jest mój wdrażania, aby zobaczyć większe emotikony, czy wiadomość nie zawiera tekstu

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

Jak ta odpowiedź na pytanie? – Pac0

Powiązane problemy