2011-06-22 13 views
6

Jak napisano w nagłówku, chcę przekonwertować znaki zenkaku na hankaku i vice-vrsa w C#, ale nie mogę wymyślić, jak to zrobić. Więc powiedz "ラ ー メ ン" na "ラ ー メ ン" i na odwrót. Czy byłoby możliwe zapisanie tego w metodzie, która automatycznie określa, w jaki sposób należy przejść, w zależności od formatu danych wejściowych?Konwertowanie znaków zenkaku na hankaku i vice versa w C#

Odpowiedz

2

Można użyć metody Strings.StrConv() włączając odniesienie do Microsoft.VisualBasic.dll, czy można p/wywołać LCMapString() natywną funkcję:

private const uint LOCALE_SYSTEM_DEFAULT = 0x0800; 
private const uint LCMAP_HALFWIDTH = 0x00400000; 

public static string ToHalfWidth(string fullWidth) 
{ 
    StringBuilder sb = new StringBuilder(256); 
    LCMapString(LOCALE_SYSTEM_DEFAULT, LCMAP_HALFWIDTH, fullWidth, -1, sb, sb.Capacity); 
    return sb.ToString(); 
} 

[DllImport("kernel32.dll", CharSet = CharSet.Unicode)] 
private static extern int LCMapString(uint Locale, uint dwMapFlags, string lpSrcStr, int cchSrc, StringBuilder lpDestStr, int cchDest); 

i można również odwrotnie:

private const uint LCMAP_FULLWIDTH = 0x00800000; 

public static string ToFullWidth(string halfWidth) 
{ 
    StringBuilder sb = new StringBuilder(256); 
    LCMapString(LOCALE_SYSTEM_DEFAULT, LCMAP_FULLWIDTH, halfWidth, -1, sb, sb.Capacity); 
    return sb.ToString(); 
} 

Jeśli chodzi o wykrywanie formatu wejściowego łańcucha, nie mam pojęcia o łatwym sposobie, nie dokonując najpierw konwersji i nie porównując wyników. (Co się stanie, jeśli ciąg zawiera znaki o pełnej i połówkowej szerokości?)

+0

Dzięki za sugestię. To w zasadzie odpowiada na moje pytanie. Szkoda, że ​​nie ma prostego sposobu na połączenie tych dwóch funkcji, aby konwersja została wykonana automatycznie. –

+0

Tak czy inaczej, zachowanie będzie niejednoznaczne. Jeśli podaję "ラ ー メ ン" (uwaga pierwszy znak jest w połowie szerokości) jako dane wejściowe do połączonej funkcji, czy wypiszesz "ラ ー メ ン" (konwertuj char-by-char), "ラ ー メ ン" (przekonwertuj na podstawie pierwszego znaku), lub "ラ ー メ ン "(konwersja na podstawie większości)? –

+0

Masz całkowitą rację, to jest dość skomplikowane ... Robię to, aby podświetlić ciągi znaków w ciągu znaków zawierających znaki japońskie. Wydaje mi się, że w tym przypadku pokrycie wszystkich możliwości wymagałoby zbyt dużej mocy obliczeniowej, aby nie przyniosło to zbyt dużego pożytku użytkownikowi końcowemu. Skończyło się na tym, co zasugerowałeś przy okazji, zamieniając się na zenkaku i hankaku, a następnie porównując oba, aby zobaczyć, czy coś się stało, więc mogę wyeliminować kanji. Dzięki za pomoc! –

1

Jednym ze sposobów jest skompilowanie listy wszystkich znaków, które chcesz przekonwertować, oraz sposobu wzajemnego odwzorowania, a następnie powtórzenie łańcucha wejściowego i zastąpienie wszystkich znaków na liście ich odpowiednikami.

var fullToHalf = new Dictionary<char, char> 
{ 
    ... 
    { '\u30E9', '\uFF97' }, // KATAKANA LETTER RA -> HALFWIDTH KATAKANA LETTER RA 
    { '\u30EA', '\uFF98' }, // KATAKANA LETTER RI -> HALFWIDTH KATAKANA LETTER RI 
    ... 
}; 

var halfToFull = fullToHalf.ToDictionary(kv => kv.Value, kv => kv.Key); 

var input = "\u30E9"; 

var isFullWidth = input.All(ch => fullToHalf.ContainsKey(ch)); 
var isHalfWidth = input.All(ch => halfToFull.ContainsKey(ch)); 

var result = new string(input.Select(ch => fullToHalf[ch]).ToArray()); 
// result == "\uFF97" 

Unicode Chart: Halfwidth and Fullwidth Forms (FF00-FFEF)

+0

Dzięki za sugestię. Myślałem o czymś takim za pomocą string.Członki i tablice zawierające wszystkie postacie, ale zastanawiam się nad czasem, który zajmie. Słownik wydaje się być lepszy, więc mógłbym spróbować. –

+0

Wystarczy powiedzieć: bardzo dziękuję za sugestię. Podoba mi się podejście, ale było to zbyt skomplikowane, co starałem się osiągnąć. Również jednym potencjalnym problemem, jaki mam z tym jest potrzeba wcześniejszego tworzenia słowników ... Trochę dziwne, że powinien to być jedyny sposób, aby zrobić to w czystym C#, gdy VB ma metodę StrConv(). –

Powiązane problemy