Come posso convertire sequenze di escape Unicode in caratteri Unicode in una stringa .NET?

Supponiamo che tu abbia caricato un file di testo in una stringa e desideri convertire tutti gli escape Unicode in veri e propri caratteri Unicode all’interno della stringa.

Esempio:

“Quanto segue è la metà superiore di un carattere integrale in Unicode ‘\ u2320’, e questa è la metà inferiore ‘\ U2321’.”

La risposta è semplice e funziona bene con le stringhe fino a diverse migliaia di caratteri.

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

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

Il primo esempio mostra la sostituzione effettuata utilizzando un’espressione lambda (C # 3.0) e la seconda utilizza un delegato che dovrebbe funzionare con C # 2.0.

Per analizzare ciò che sta accadendo qui, per prima cosa creiamo un’espressione regolare:

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

Quindi chiamiamo Replace () con la stringa ‘result’ e un metodo anonimo (espressione lambda nel primo esempio e il delegato nel secondo – il delegato potrebbe anche essere un metodo regolare) che converte ogni espressione regolare che si trova nella stringa .

L’escape Unicode viene elaborato in questo modo:

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

Ottieni la stringa che rappresenta la parte numerica dell’uscita (salta i primi due caratteri).

 match.Value.Substring(2) 

Analizza quella stringa utilizzando Int32.Parse () che accetta la stringa e il formato numerico che la funzione Parse () dovrebbe prevedere, in questo caso un numero esadecimale.

 NumberStyles.HexNumber 

Quindi assegniamo il numero risultante a un carattere Unicode:

 (char) 

E infine chiamiamo ToString () sul carattere Unicode che ci fornisce la sua rappresentazione di stringa che è il valore passato a Replace ():

 .ToString() 

Nota: anziché prendere il testo da convertire con una chiamata Substring, è ansible utilizzare GroupCollection del parametro match e un’espressione secondaria nell’espressione regolare per acquisire solo il numero (‘2320’), ma è più complicato e meno leggibile.

Rifattorizzato un po ‘di più:

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

Questo è l’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()) 

Penso che sia meglio aggiungere le piccole lettere alla tua espressione regolare. Ha funzionato meglio per me.

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