Подтвердить что ты не робот

Как преобразовать escape-последовательности Unicode в символы Unicode в строке .NET?

Скажем, вы загрузили текстовый файл в строку, и вы хотите преобразовать все escape-последовательности Unicode в фактические символы Unicode внутри строки.

Пример:

"Ниже приведена верхняя половина интегрального символа в Unicode '\ u2320', а это нижняя половина '\ U2321'."

4b9b3361

Ответ 1

Ответ прост и хорошо работает со строками не менее нескольких тысяч символов.

Пример 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() );

Пример 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(); } );

Первый пример показывает, что замена выполняется с использованием лямбда-выражения (С# 3.0), а вторая использует делегат, который должен работать с С# 2.0.

Чтобы разрушить то, что происходит здесь, сначала создаем регулярное выражение:

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

Затем мы вызываем Replace() строкой "result" и анонимным методом (выражение lambda в первом примере и делегат во втором - делегат также может быть обычным методом), который преобразует каждое регулярное выражение, которое найдено в строке.

Выделение Unicode обрабатывается следующим образом:

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

Получить строку, представляющую числовую часть escape (пропустить первые два символа).

match.Value.Substring(2)

Разберите эту строку, используя Int32.Parse(), которая берет строку и формат чисел, которые должна ожидать функция Parse(), которая в этом случае является шестнадцатеричным номером.

NumberStyles.HexNumber

Затем мы передаем результирующее число символу Unicode:

(char)

И, наконец, мы вызываем ToString() в символе Unicode, который дает нам свое строковое представление, которое является значением, возвращаемым в Replace():

.ToString()

Примечание. Вместо того, чтобы захватывать текст, подлежащий преобразованию, с помощью вызова подстроки, вы можете использовать параметр соответствия GroupCollection и подвыражения в регулярном выражении для захвата только числа ('2320'), но это более сложное и менее читаемое.

Ответ 2

Рефакторинг немного больше:

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

Ответ 3

Это эквивалент 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())

Ответ 4

Думаю, вам лучше добавить маленькие буквы в ваше регулярное выражение. Это сработало лучше для меня.

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