Замена символов в 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 не работает. Как мне решить эту проблему?
Это образец входного файла:
Димакасо Мокгало Мама Ратлади Коос Нель Pàsèkà Modisè Иеремия Мореми Кхетиве Бутхелези Tiànà Pillày Viviàn Màswàngànyè Тирешан Редди Вад Корнелиус Энос Нетсимбупфе
Это вывод, если используется: line = line.Replace ('à', 'a');:
Ch�rl�n� Kirst�n M�m� R�tl�di Koos Nïl½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 для удаления 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);
Я часто использую метод расширения, основанный на версии, предоставленной Даной. Быстрое объяснение:
- Нормализация для формирования D разбивает символы, такие как è, 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(String, Encoding) при чтении файлов, которые могут содержать импортированный текст, поскольку нераспознанные символы могут читаться неправильно.
Что такое кодировка C:/Joiner.csv
в? Может быть, вы должны использовать другую перегрузку для File.ReadAllText
где вы сами указываете кодировку ввода?
Делать это простым способом. Приведенный ниже код заменит все специальные символы на символы ASCII всего за 2 строки кода. Это дает тот же результат, что и решение Жюльена Ронкалья.
byte[] bytes = System.Text.Encoding.GetEncoding("Cyrillic").GetBytes(inputText);
string outputText = System.Text.Encoding.ASCII.GetString(bytes);
Использовать этот:
if (line.Contains(“OldChar”))
{
line = line.Replace(“OldChar”, “NewChar”);
}
Похоже, что вы хотите сделать, это преобразовать расширенный ASCII (восьмибитный) в ASCII (семибитный) - так что поиск может помочь.
Я видел библиотеки для обработки этого на других языках, но никогда не приходилось делать это в C#, хотя это выглядит несколько поучительно: