¿Cómo convierto las secuencias de escape de Unicode a caracteres Unicode en una cadena .NET?

Supongamos que ha cargado un archivo de texto en una cadena y desea convertir todos los escapes Unicode en caracteres Unicode reales dentro de la cadena.

Ejemplo:

“La siguiente es la mitad superior de un carácter integral en Unicode ‘\ u2320’, y esta es la mitad inferior ‘\ U2321’.”

La respuesta es simple y funciona bien con cadenas de hasta varios miles de caracteres.

Ejemplo 1:

Regex rx = new Regex( @"\\[uU]([0-9A-F]{4})" ); result = rx.Replace( result, match => ((char) Int32.Parse(match.Value.Substring(2), NumberStyles.HexNumber)).ToString() ); 

Ejemplo 2:

 Regex rx = new Regex( @"\\[uU]([0-9A-F]{4})" ); result = rx.Replace( result, delegate (Match match) { return ((char) Int32.Parse(match.Value.Substring(2), NumberStyles.HexNumber)).ToString(); } ); 

El primer ejemplo muestra que el reemplazo se realizó usando una expresión lambda (C # 3.0) y el segundo usa un delegado que debería funcionar con C # 2.0.

Para desglosar lo que está sucediendo aquí, primero creamos una expresión regular:

 new Regex( @"\\[uU]([0-9A-F]{4})" ); 

Luego llamamos Reemplazar () con la cadena ‘resultado’ y un método anónimo (expresión lambda en el primer ejemplo y el delegado en el segundo – el delegado también podría ser un método regular) que convierte cada expresión regular que se encuentra en la cadena .

El escape Unicode se procesa así:

 ((char) Int32.Parse(match.Value.Substring(2), NumberStyles.HexNumber)).ToString(); }); 

Obtenga la cadena que representa la parte numérica del escape (omita los primeros dos caracteres).

 match.Value.Substring(2) 

Analice esa cadena usando Int32.Parse () que toma la cadena y el formato numérico que la función Parse () debe esperar, que en este caso es un número hexadecimal.

 NumberStyles.HexNumber 

Luego lanzamos el número resultante a un carácter Unicode:

 (char) 

Y finalmente llamamos a ToString () en el carácter Unicode que nos da su representación de cadena, que es el valor pasado de nuevo a Replace ():

 .ToString() 

Nota: En lugar de agarrar el texto que se convertirá con una llamada de Subcadena, podría usar la Recolección de grupo del parámetro de coincidencia y una subexpresiones en la expresión regular para capturar solo el número (‘2320’), pero eso es más complicado y menos legible.

Refactorizado un poco más:

 Regex regex = new Regex (@"\\U([0-9A-F]{4})", RegexOptions.IgnoreCase); string line = "..."; line = regex.Replace (line, match => ((char)int.Parse (match.Groups[1].Value, NumberStyles.HexNumber)).ToString ()); 

Este es el equivalente de VB.NET:

 Dim rx As New RegularExpressions.Regex("\\[uU]([0-9A-Fa-f]{4})") result = rx.Replace(result, Function(match) CChar(ChrW(Int32.Parse(match.Value.Substring(2), Globalization.NumberStyles.HexNumber))).ToString()) 

Creo que es mejor que agregue las letras minúsculas a su expresión regular. Funcionó mejor para mí.

 Regex rx = new Regex(@"\\[uU]([0-9A-Fa-f]{4})"); result = rx.Replace(result, match => ((char) Int32.Parse(match.Value.Substring(2), NumberStyles.HexNumber)).ToString());