Замена символов в C# (ascii)

у меня есть файл с такими символами: à, è, î, ò, ∙ - À. Что мне нужно сделать, так это заменить эти символы обычными символами, например: à = a, è = e и так далее..... Это мой код до сих пор:

StreamWriter sw = new StreamWriter(@"C:/JoinerOutput.csv");
string path = @"C:/Joiner.csv";
string line = File.ReadAllText(path);

if (line.Contains("à"))
{
    string asAscii = Encoding.ASCII.GetString(Encoding.Convert(Encoding.UTF8, Encoding.GetEncoding(Encoding.ASCII.EncodingName, new EncoderReplacementFallback("a"), new DecoderExceptionFallback()), Encoding.UTF8.GetBytes(line)));
    Console.WriteLine(asAscii);
    Console.ReadLine();

    sw.WriteLine(asAscii);
    sw.Flush();
}

В основном это ищет файл для определенного символа и заменяет его другим. Проблема в том, что мое утверждение if не работает. Как мне решить эту проблему?

Это пример входного файла:

Dimàkàtso Mokgàlo
Màmà Ràtlàdi
Koos Nèl
Pàsèkà Modisè
Jèrèmiàh Morèmi
Khèthiwè Buthèlèzi
Tiànà Pillày
Viviàn Màswàngànyè
Thirèshàn Rèddy
Wàdè Cornèlius
ènos Nètshimbupfè

этот является выходом, если используется: line = line.Заменить ("à", "a");:

Ch�rl�n� Kirst�n
M�m� R�tl�di
Koos N�l
P�s�k� Modis�
J�r�mi�h Mor�mi
Kh�thiw� Buth�l�zi
Ti�n� Pill�y
Vivi�n M�sw�ng�ny�
Thir�sh�n R�ddy
W�d� Corn�lius
�nos N�tshimbupf�

С моим кодом символ будет полностью удален

7 ответов


Не знаю, полезно ли это, но во внутреннем инструменте для записи сообщения на светодиодном экране у нас есть следующие замены (я уверен, что есть более интеллектуальные способы сделать эту работу для таблиц unicode, но этого достаточно для этого небольшого внутреннего инструмента) :

        strMessage = Regex.Replace(strMessage, "[éèëêð]", "e");
        strMessage = Regex.Replace(strMessage, "[ÉÈËÊ]", "E");
        strMessage = Regex.Replace(strMessage, "[àâä]", "a");
        strMessage = Regex.Replace(strMessage, "[ÀÁÂÃÄÅ]", "A");
        strMessage = Regex.Replace(strMessage, "[àáâãäå]", "a");
        strMessage = Regex.Replace(strMessage, "[ÙÚÛÜ]", "U");
        strMessage = Regex.Replace(strMessage, "[ùúûüµ]", "u");
        strMessage = Regex.Replace(strMessage, "[òóôõöø]", "o");
        strMessage = Regex.Replace(strMessage, "[ÒÓÔÕÖØ]", "O");
        strMessage = Regex.Replace(strMessage, "[ìíîï]", "i");
        strMessage = Regex.Replace(strMessage, "[ÌÍÎÏ]", "I");
        strMessage = Regex.Replace(strMessage, "[š]", "s");
        strMessage = Regex.Replace(strMessage, "[Š]", "S");
        strMessage = Regex.Replace(strMessage, "[ñ]", "n");
        strMessage = Regex.Replace(strMessage, "[Ñ]", "N");
        strMessage = Regex.Replace(strMessage, "[ç]", "c");
        strMessage = Regex.Replace(strMessage, "[Ç]", "C");
        strMessage = Regex.Replace(strMessage, "[ÿ]", "y");
        strMessage = Regex.Replace(strMessage, "[Ÿ]", "Y");
        strMessage = Regex.Replace(strMessage, "[ž]", "z");
        strMessage = Regex.Replace(strMessage, "[Ž]", "Z");
        strMessage = Regex.Replace(strMessage, "[Ð]", "D");
        strMessage = Regex.Replace(strMessage, "[œ]", "oe");
        strMessage = Regex.Replace(strMessage, "[Œ]", "Oe");
        strMessage = Regex.Replace(strMessage, "[«»\u201C\u201D\u201E\u201F\u2033\u2036]", "\"");
        strMessage = Regex.Replace(strMessage, "[\u2026]", "...");

следует отметить, что если в большинстве языков текст все еще понятен после такого обращения, это не всегда так и часто заставляет читателя ссылаться на контекст предложения чтобы понять это. Не то, что ты хочешь, если у тебя есть выбор.


обратите внимание, что правильным решением было бы использовать таблицы unicode, заменяя символы интегрированными диакритиками с их "комбинированной диакритической меткой(знаками)"+символьной формой, а затем удаляя диакритики...


другие прокомментировали использование таблицы подстановки Unicode для удаления диакритики. Я сделал быстрый поиск Google и нашел . Код бесстыдно скопирован, (отформатирован) и размещен ниже:

using System;
using System.Text;
using System.Globalization;

public static class Remove
{
    public static string RemoveDiacritics(string stIn)
    {
        string stFormD = stIn.Normalize(NormalizationForm.FormD);
        StringBuilder sb = new StringBuilder();

        for(int ich = 0; ich < stFormD.Length; ich++) {
            UnicodeCategory uc = CharUnicodeInfo.GetUnicodeCategory(stFormD[ich]);
            if(uc != UnicodeCategory.NonSpacingMark) {
                sb.Append(stFormD[ich]);
            }
        }

        return(sb.ToString().Normalize(NormalizationForm.FormC));
    }
}

Итак, ваш код может очистить вход по телефону:

line = Remove.RemoveDiacritics(line);

Я часто использую метод расширения на основе версии, предоставленной Даной. Краткое описание:

  • нормализация в форме D шпагат charactes как è до e и несамостоятельный `
  • из этого удаляются символы nospacing
  • результат нормализуется обратно в форму D (Я не уверен, что это необходимо)

код:

using System.Linq;
using System.Text;
using System.Globalization;

// namespace here
public static class Utility
{
    public static string RemoveDiacritics(this string str)
    {
        if (str == null) return null;
        var chars =
            from c in str.Normalize(NormalizationForm.FormD).ToCharArray()
            let uc = CharUnicodeInfo.GetUnicodeCategory(c)
            where uc != UnicodeCategory.NonSpacingMark
            select c;

        var cleanStr = new string(chars.ToArray()).Normalize(NormalizationForm.FormC);

        return cleanStr;
    }
}

Почему вы все усложнять?

line = line.Replace('à', 'a');

обновление:

документы на File.ReadAllText говорят:

этот метод пытается автоматически определить кодировку файла на основе наличие меток порядка байтов. Форматы кодирования UTF-8 и UTF-32 (как обратный порядок байтов и прямой порядок байтов) может быть обнаружен.

используйте ReadAllText (строка, кодировка) перегрузка метода при чтении файлов это может содержать импортированный текст, потому что непризнанные символы могут не правильно прочитал.

что такое кодировка C:/Joiner.csv в? Возможно, вам следует использовать другую перегрузку для File.ReadAllText где вы сами указываете кодировку ввода?


используйте этот:

     if (line.Contains(“OldChar”))
     {
        line = line.Replace(“OldChar”, “NewChar”);
     }

делать это простым способом. Приведенный ниже код заменит все специальные символы символами ASCII всего в 2 строках кода. Это дает вам тот же результат, что и решение Жюльена Ронкальи.

byte[] bytes = System.Text.Encoding.GetEncoding("Cyrillic").GetBytes(inputText);
string outputText = System.Text.Encoding.ASCII.GetString(bytes);

похоже, что вы хотите сделать, это преобразовать расширенный ASCII (восемь бит) в ASCII (семь бит)-так что поиск этого может помочь.

Я видел библиотеки, чтобы справиться с этим на других языках, но никогда не приходилось делать это на C#, похоже, это может быть несколько поучительным, хотя:

преобразование двух символов ascii в их "соответствующее" одно символьное расширенное представление ascii