2015-08-21 15 views
6

Ben, örneğin, Cyclone ve C# ve .NET tanımlanan Japanese Castle oluşan bu Unicode dizesi, kullandığı UTF-16 CLR dize kodlama için:Dizede karakterleri UTF-32 ondalık değerleri olarak nasıl okurum?

var value = ""; 

Bunu işaretlerseniz, C#, UTF-16 kodlu dizeleri kullandığı için çok hızlı bulursunuz, bu nedenle bu nedenlerden dolayı, her karakterde sadece döngü oluşturamaz ve UTF-32 ondalık değerini alamıyorum: foreach (var character in value) result = (ulong)character;. Bu soruya, herhangi bir dizede her karakter için UTF-32 ondalık değerini nasıl alabilirim?

Cyclone 127744 olmalı ve Japonca Kale 127983 olmalıdır, ancak herhangi bir C# dizesini alabilen ve her zaman içindeki her karakterden bir UTF-32 ondalık değeri üretebilen genel bir yanıt arıyorum.

Hatta Char.ConvertToUtf32 bir göz alarak denedim ama bu örnekte, eğer sorunlu gibi görünüyor: Bu anlarım, nasıl Yani 6 bir uzunluğa sahiptir

var value = "ac"; 

zaman yeni bir karakter başlar? Örneğin:

public static int ConvertToUtf32(
    char highSurrogate, 
    char lowSurrogate 
) 

Ama benim de bu kullanmak için ben vekil çiftleri olduğunda anlamaya ihtiyacımız:

Char.ConvertToUtf32(value, 0) 97 int 
Char.ConvertToUtf32(value, 1) 127744 int 
Char.ConvertToUtf32(value, 2) 'Char.ConvertToUtf32(value, 2)' threw an exception of type 'System.ArgumentException' int {System.ArgumentException} 
Char.ConvertToUtf32(value, 3) 99 int 
Char.ConvertToUtf32(value, 4) 127983 int 
Char.ConvertToUtf32(value, 5) 'Char.ConvertToUtf32(value, 5)' threw an exception of type 'System.ArgumentException' int {System.ArgumentException} 

de bulunmaktadır. Nasıl yaparsın?

+1

http://stackoverflow.com/questions/5903113/how-to-retrieve-the-unicode-decimal-representation-of-the-chars-in-a-string-cont – MethodMan

+0

@MethodMan sayesinde kabul Oraya cevap vereceğim ama bunu .NET'te yapmanın daha zarif bir yolu olduğunu umuyordum. – Alexandru

+0

kimi zaman en şık şekilde görünebilir ya da biraz karmaşık görünür .. Kod yapısıyla ilgili olarak – MethodMan

cevap

5

İşte bunu yapmanın bir yolunu gösteren bir uzantı yöntemidir. Buradaki fikir, dizenin her bir karakterini değiştirebilmeniz ve unicode değerini elde etmek için char.ConvertToUtf32(string, index) kullanmanızdır. Döndürülen değer 0xFFFF'dan büyükse, unicode değerinin bir temsilci karakter kümesinden oluştuğunu bilirsiniz ve indeks değerini 2. vekil karakterini atlamak için buna göre ayarlayabilirsiniz.

uzatma yöntemi:

public static IEnumerable<int> GetUnicodeCodePoints(this string s) 
{ 
    for (int i = 0; i < s.Length; i++) 
    { 
     int unicodeCodePoint = char.ConvertToUtf32(s, i); 
     if (unicodeCodePoint > 0xffff) 
     { 
      i++; 
     } 
     yield return unicodeCodePoint; 
    } 
} 

Örnek kullanım:

static void Main(string[] args) 
{ 
    string s = "ac"; 

    foreach(int unicodeCodePoint in s.GetUnicodeCodePoints()) 
    { 
     Console.WriteLine(unicodeCodePoint); 
    } 
} 
+0

Mükemmel, teşekkürler! – Alexandru

4

Çözelti 1

string value = ""; 
byte[] rawUtf32AsBytes = Encoding.UTF32.GetBytes(value); 
int[] rawUtf32 = new int[rawUtf32AsBytes.Length/4]; 
Buffer.BlockCopy(rawUtf32AsBytes, 0, rawUtf32, 0, rawUtf32AsBytes.Length); 

Çözelti 2

string value = ""; 
List<int> rawUtf32list = new List<int>(); 
for (int i = 0; i < value.Length; i++) 
{ 
    if (Char.IsHighSurrogate(value[i])) 
    { 
     rawUtf32list.Add(Char.ConvertToUtf32(value[i], value[i + 1])); 
     i++; 
    } 
    else 
     rawUtf32list.Add((int)value[i]); 
} 
+0

Ayrıca 'Char.IsHighSurrogate' kullanmak için harika bir cevap – Alexandru

İlgili konular