Почему при снятии акцентов/диакритических знаков
Я использую этот метод для удаления акцентов из строк:
static string RemoveAccents(string input)
{
string normalized = input.Normalize(NormalizationForm.FormKD);
StringBuilder builder = new StringBuilder();
foreach (char c in normalized)
{
if (char.GetUnicodeCategory(c) !=
UnicodeCategory.NonSpacingMark)
{
builder.Append(c);
}
}
return builder.ToString();
}
но этот метод оставляет đ как đ и не меняет его на d, хотя d является его базой char.
вы можете попробовать его с помощью этой вводной строки "æøåáâăäĺćččęęěěíěďđďđďđďđňňňőőőőůůůűűýţ"
Что такого особенного в письме?
Ответы
Ответ 1
Ответ за то, почему он не работает, заключается в том, что утверждение, что "d является его базой char", является ложным. U + 0111 (LATIN SMALL LETTER D WITH STROKE) имеет категорию Unicode "Letter, Lowercase" и не имеет разбиения на разложение (т.е. Не разлагается до "d", за которым следует комбинационная метка).
"đ".Normalize(NormalizationForm.FormD)
просто возвращает "đ"
, который не удаляется контуром, потому что он не является меткой без пробела.
Аналогичная проблема будет существовать для "ø" и других букв, для которых Unicode не обеспечивает отображение разложения. (И если вы пытаетесь найти "лучший" ASCII-символ для представления буквы Unicode, этот подход не будет работать вообще для кириллических, греческих, китайских или других нелатинских алфавитов, вы также столкнетесь с проблемами, если вы хотели транслитерировать "ß" на "ss", например. Использование библиотеки типа UnidecodeSharp может помочь.)
Ответ 2
Я должен признать, что я не уверен, почему это работает, но он уверен, что
var str = "æøåáâăäĺćçčéęëěíîďđńňóôőöřůúűüýţ";
var noApostrophes = Encoding.ASCII.GetString(Encoding.GetEncoding("Cyrillic").GetBytes(str));
= > "aoaaaaalccceeeeiiddnnooooruuuuyt"
Ответ 3
" D с инсультом" (Википедия) используется на нескольких языках и, по-видимому, считается во всех них отдельной буквой - - и поэтому он остается неизменным.
Ответ 4
это должно работать
private static String RemoveDiacritics(string text)
{
String normalized = text.Normalize(NormalizationForm.FormD);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < normalized.Length; i++)
{
Char c = normalized[i];
if (CharUnicodeInfo.GetUnicodeCategory(c) != UnicodeCategory.NonSpacingMark)
sb.Append(c);
}
return sb.ToString();
}