2011-06-22 13 views
6

Como dice en la línea del encabezado, quiero convertir caracteres zenkaku en hankaku y vice-vrsa en C#, pero no puedo encontrar la manera de hacerlo. Entonces, diga "ラ ー メ to" a "ラ ー メ ン" y viceversa. ¿Sería posible escribir esto en un método que determine automáticamente en qué dirección debe ir la conversión, en función del formato de la entrada?Conversión de caracteres zenkaku a hankaku y viceversa en C#

Respuesta

2

Usted puede utilizar el método Strings.StrConv() mediante la inclusión de una referencia a Microsoft.VisualBasic.dll, o puede p/invocar la función nativa LCMapString():

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); 

y puedes también haga lo contrario:

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(); 
} 

En cuanto a la detección del formato de la cadena de entrada, no estoy al tanto de una manera fácil sin hacer primero una conversión y comparar los resultados. (¿Qué pasa si la cadena contiene caracteres de ancho completo y medio ancho?)

+0

Gracias por la sugerencia. Esto básicamente responde mi pregunta. Una pena que no haya una manera fácil de combinar las dos funciones para que la conversión se realice automáticamente. –

+0

Hacerlo de todos modos será un comportamiento ambiguo. Si doy "ラ ー メ ン" (note que el primer carácter es de ancho medio) como entrada a su función combinada, ¿da salida "ラ ー メ (" (conversión de carácter por charla), "ラ ー メ (" (conversión basada en el primer carácter) o "ラ ー メ ン "(¿se convierte según la mayoría)? –

+0

Tiene toda la razón, se vuelve bastante complicado ... Estoy haciendo esto para resaltar las subcadenas en una cadena que contenga caracteres japoneses. Supongo que en este caso cubrir todas las posibilidades tomaría demasiada potencia de procesamiento para no mucho beneficio para el usuario final. Terminé haciendo lo que sugeriste por cierto, convirtiéndome en zenkaku y hankaku y luego comparando los dos para ver si sucedía algo, para poder eliminar el kanji. ¡Gracias por la ayuda! –

1

Un enfoque consiste en compilar una lista de todos los caracteres que desea convertir y cómo se correlacionan entre sí, y luego iterar la cadena de entrada y reemplazar todos los caracteres de la lista con su equivalente.

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

Gracias por la sugerencia. Pensé en algo como esto con una cadena. Contiene y arreglos que contienen todos los personajes, pero me pregunto sobre el tiempo que tomaría. Un diccionario parece más ordenado, así que podría intentarlo. –

+0

Solo para decir: muchas gracias por la sugerencia. Me gusta el enfoque, pero fue demasiado complejo para lo que estaba tratando de lograr. También un problema potencial que tengo con esto es la necesidad de crear los diccionarios de antemano ... Un poco extraño que esta debería ser la única manera de hacer esto en C# puro cuando VB tiene el método StrConv(). –

Cuestiones relacionadas