2008-10-08 15 views

Respuesta

45

La respuesta es simple y funciona bien con cadenas de hasta varios miles de caracteres como mínimo.

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 la sustitución de ser hecho utilizando una expresión lambda (C# 3.0) y la segunda utiliza un delegado que debe trabajar con C# 2.0.

para romper lo que está pasando aquí, en primer lugar crear una expresión regular:

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

entonces llamamos Reemplazar() con el 'resultado' de cuerda 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 Unicode de escape se procesa de esta manera:

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

obtener la cadena que representa el número de parte de la fuga (saltar los dos primeros caracteres).

match.Value.Substring(2) 

analizar dicha cadena usando Int32.Parse() que toma la cuerda y el formato de número que la función Parse() debe esperar que en este caso es un número hexadecimal.

NumberStyles.HexNumber 

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

(char) 

Y finalmente llamamos ToString() en el carácter Unicode que nos da la representación de cadena que es el valor que se pasa de nuevo a reemplazar():

.ToString() 

Nota: en vez de agarrar el texto que se convierte con una subcadena llamada que podría utilizar el parámetro de GroupCollection partido, y una subexpresión en la expresión regular para capturar solo el número ('2320'), pero eso es más complicado y menos legible.

+2

\ u y \ U deben ser tratados de manera diferente - \ u especifica 4 dígitos hexadecimales (16 bits), donde \ U especifica 8 (32 bits): un punto de código Unicode tiene 21 bits de longitud. Además, debe usar el método char.ConvertFromUtf32() en lugar de un molde. –

+0

He visto \ uy \ U documentado ambas formas, aunque la especificación actual del lenguaje C# indica 4 bytes hexadecimales para \ uy 8 bytes hexadecimales para \ U. En cualquier caso, \ U con solo 4 dígitos hexadecimales se procesa correctamente. Tengo que comprobar si ConvertFromUtf32() es funcionalmente diferente de un elenco. –

+0

Sí, leí la opción ignorar caso en la segunda parte de la publicación después de darme cuenta. Gracias de todos modos. :) – Echilon

8

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

creo que se agrega mejor las letras pequeñas de la 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()); 
5

Este es el equivalente 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()) 
Cuestiones relacionadas