Заменить специальные символы в файлах самым быстрым способом? - PullRequest
0 голосов
/ 13 мая 2018

У меня есть несколько файлов, которые содержат специальные символы, такие как é,ã,Δ,Ù и т. Д. Я хочу заменить их на 4-значные значения NCR (шестнадцатеричные). Я попробовал описанный ниже метод, но не уверен, что это самый быстрый способ достижения моей цели ...

var entities = new[]
{
new { ser = "\u00E9", rep = @"é" },
new { ser = "\u00E3", rep = @"ã" },
new { ser = "\u00EA", rep = @"ê" },
new { ser = "\u00E1", rep = @"á" },
new { ser = "\u00C1", rep = @"Á" },
new { ser = "\u00C9", rep = @"É" },
new { ser = "\u0394", rep = @"Δ" },
new { ser = "\u03B1", rep = @"α" },
new { ser = "\u03B2", rep = @"β" },
new { ser = "\u00B1", rep = @"±" },
//... so on
};

var files = Directory.GetFiles(path, "*.xml");
foreach (var file in files)
{
    string txt = File.ReadAllText(file);

    foreach (var entity in entities)
    {
        if (Regex.IsMatch(txt, entity.ser))
        {
            txt = Regex.Replace(txt, entity.ser, entity.rep);
        }
    };
    File.WriteAllText(file, txt);
}

Есть ли более быстрый и эффективный способ сделать это?

1 Ответ

0 голосов
/ 13 мая 2018

Из комментариев вы хотите заменить символы Юникода (например, Ù) на их значение Юникода (& # x00D9). Regex.Replace, вероятно, будет лучшим способом для достижения этого.

Вот цикл обработки файлов:

var files = Directory.GetFiles(path, "*.xml");
foreach (var file in files)
{
    string txt = File.ReadAllText(file);

    string newTxt = Regex.Replace(
        txt,
        @"([^\u0000-\u007F]+)",
        HandleMatch);

    File.WriteAllText(file, newTxt);
}

А вот оценщик матча:

private static char[] replacements = new[]
{
    'ø',
    'Ù'
};

private static string HandleMatch(Match m)
{
    // The pattern for the Regex will only match a single character, so get that character
    char c = m.Value[0];

    // Check if this is one of the characters we want to replace
    if (!replacements.Contains(c))
    {
        return m.Value;
    }

    // Convert the character to the 4 hex digit code
    string code = ((int) c).ToString("X4");

    // Format and return the code
    return "&#x" + code;
}

В цикле вам нужно только прочитать файл один раз, тогда метод Regex.Replace будет обрабатывать замену всех экземпляров во входных данных. Шаблон для регулярного выражения будет соответствовать всему, что не находится в диапазоне 0x00 - 0x7f, которые будут первыми 255 символами (символы ASCII).

Если вам нужно заменить только определенные символы Юникода, вам нужно будет составить список этих символов и проверить значение 'c' в функции HandleMatch() по этому списку.

Комментарии к спектаклю: Вы пытаетесь выполнить выборочную замену символов для набора файлов. Как минимум, вам нужно будет прочитать каждый файл в память, а затем изучить каждый символ, чтобы убедиться, что он соответствует вашим критериям.

Более производительный параметр может состоять в том, чтобы построить таблицу поиска символов, а затем строки замены для каждого. Компромисс был бы в том, что если бы у вас был большой список символов, которые нужно было заменить, таблица быстро стала бы громоздкой для обслуживания. Вы также оставляете открытым риск ошибок в таблице замены, которую можно найти больше.

...