Как мне перевести 8-битные символы в 7-битные? (т.е. от U до U) - PullRequest
20 голосов
/ 26 сентября 2008

Я ищу псевдокод или пример кода для преобразования старших битовых символов ascii (например, Ü, который расширен как ascii 154) в U (который является ascii 85).

Мое первоначальное предположение состоит в том, что, поскольку существует только около 25 символов ASCII, которые похожи на 7-разрядные символы ASCII, необходимо использовать массив перевода.

Дайте мне знать, если вы можете думать о чем-нибудь еще.

Ответы [ 15 ]

28 голосов
/ 06 апреля 2012

Для пользователей .NET статья в CodeProject (благодаря подсказке GvS ) действительно отвечает на вопрос более правильно, чем любая другая, которую я до сих пор видел.

Однако код в этой статье (в решении № 1) громоздок. Вот компактная версия:

// Based on http://www.codeproject.com/Articles/13503/Stripping-Accents-from-Latin-Characters-A-Foray-in
private static string LatinToAscii(string inString)
{
    var newStringBuilder = new StringBuilder();
    newStringBuilder.Append(inString.Normalize(NormalizationForm.FormKD)
                                    .Where(x => x < 128)
                                    .ToArray());
    return newStringBuilder.ToString();
}

Чтобы немного расширить ответ, этот метод использует String.Normalize , который:

Возвращает новую строку, текстовое значение которой совпадает с этой строкой, но чье двоичное представление находится в указанном Unicode форма нормализации.

Конкретно в этом случае мы используем NormalizationForm FormKD, описанную в тех же документах MSDN как таковую:

FormKD - указывает, что строка Unicode нормализована с использованием декомпозиции полной совместимости.

Для получения дополнительной информации о формах нормализации Unicode см. Приложение Unicode # 15 .

17 голосов
/ 26 сентября 2008

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

11 голосов
/ 26 сентября 2008

Преобразование Ü в U действительно то, что вы хотели бы сделать? Я не знаю о других языках, но на немецком языке я стал бы Ue, стал бы oe и т. Д.

6 голосов
/ 29 сентября 2008

В кодовой странице 1251 символы кодируются двумя байтами: один для основного символа и один для варианта. Затем, когда вы кодируете обратно в ASCII, сохраняются только основные символы.

public string RemoveDiacritics(string text)
{

  return System.Text.Encoding.ASCII.GetString(System.Text.Encoding.GetEncoding(1251).GetBytes(text));

}

От: http://www.clt -services.com / blog / post / Enlever-les-accents-dans-und-chaine- (proprement) .aspx

6 голосов
/ 26 сентября 2008

Я думаю, вы просто не можете.

Обычно я делаю что-то подобное:

AccentString = 'ÀÂÄÉÈÊ [и все остальные]'
ConvertString = 'AAAEEE [и все остальные]'

Поиск символа в AccentString и замена его на тот же индекс в ConvertString

НТН

5 голосов
/ 26 сентября 2008

На самом деле, как предложено Nistist: Функция iconv существует для обработки всех странных для вас преобразований, доступна почти на всех языках программирования и имеет специальную опцию, которая пытается преобразовать символы, отсутствующие в целевом наборе, с помощью аппроксимаций.

Используйте iconv для простого преобразования вашей входной строки UTF-8 в 7-битную ASCII.

В противном случае вы всегда прекратите использовать регистр углов: 8-битный ввод, использующий другую кодовую страницу с другим набором символов (таким образом, вообще не работающий с вашей таблицей преобразования), забыл отобразить последний глупый символ с ударением (вы отобразили все серьезные / острые акценты, но забыли нанести на карту чешскую каронскую или нордическую букву '°') и т. д.

Конечно, если вы хотите применить решение к небольшой специфической проблеме (создание файловых файлов, подходящих для файловой системы, для вашей музыкальной коллекции), вам подойдут поисковые массивы (либо массив, который для каждого кода выше) 128 отображает аппроксимацию меньше 128, как предложено JeeBee, или пары источник / цель, предложенные vIceBerg, в зависимости от того, какие функции подстановки уже доступны на выбранном вами языке), потому что он быстро взламывается вместе и быстро проверяет отсутствие элементов.

1 голос
/ 08 октября 2008

Есть статья на CodeProject , которая выглядит хорошо.

Также меня заинтересовал переход с использованием кодовой страницы 1251 (см. Другой ответ).

Мне не нравятся таблицы преобразования, поскольку количество символов в Юникоде настолько велико, что вы легко пропускаете один.

1 голос
/ 26 сентября 2008

Это действительно зависит от природы ваших исходных строк. Если вы знаете кодировку строки и знаете, что это 8-битная кодировка - например, ISO Latin 1 или аналогичная - тогда достаточно простого статического массива:

static const char xlate[256] = { ..., ['é'] = 'e', ..., ['Ü'] = 'U', ... }
...
new_c = xlate[old_c];

С другой стороны, если у вас другая кодировка или вы используете строки в кодировке UTF-8, вы, вероятно, найдете функции из библиотеки ICU очень полезными.

1 голос
/ 26 сентября 2008

Хм, а почему бы просто не изменить кодировку строки с помощью iconv?

1 голос
/ 26 сентября 2008

Вы, кажется, прибили это, я думаю. 128-байтовый массив байтов, индексированный символами & 127, содержащий соответствующий 7-битный символ для 8-битного символа.

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