Замена символов в C # (ascii) - PullRequest
9 голосов
/ 28 марта 2011

У меня есть файл с такими символами, как: à, è, ì, ò, ù - À. Что мне нужно сделать, это заменить эти символы нормальными символами, например: à = 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.Replace ('à', '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 ]

18 голосов
/ 28 марта 2011

Другие прокомментировали использование таблицы поиска Unicode для удаления Diacritics. Я сделал быстрый поиск в 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);
10 голосов
/ 28 марта 2011

Не знаю, полезно ли это, но во внутреннем инструменте для написания сообщения на светодиодном экране у нас есть следующие замены (я уверен, что есть более разумные способы заставить это работать для таблиц 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, замена символов с интегрированными диакритическими знаками на их "комбинированные диакритические знаки (знаки)" + символьная форма и затем удаление диакритических знаков ...

6 голосов
/ 31 октября 2012

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

  • Нормализация для формирования D-разбиений символов, таких как è , до e и без пробелов `
  • Отсюда удаляются символы пробелов
  • Результат нормализуется обратно в форму 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;
    }
}
3 голосов
/ 28 марта 2011

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

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

Обновление:

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

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

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

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

2 голосов
/ 11 октября 2016

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

byte[] bytes = System.Text.Encoding.GetEncoding("Cyrillic").GetBytes(inputText);
string outputText = System.Text.Encoding.ASCII.GetString(bytes);
1 голос
/ 28 марта 2011

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

     if (line.Contains(“OldChar”))
     {
        line = line.Replace(“OldChar”, “NewChar”);
     }
0 голосов
/ 28 марта 2011

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...