Как перевести 8-битные символы на 7-битные символы? (т.е. от U до U)

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

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

Сообщите мне, можете ли вы придумать что-нибудь еще.

Ответ 1

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

Используйте iconv, чтобы просто преобразовать строку ввода UTF-8 в 7-битный ASCII.

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

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

Ответ 2

Для пользователей .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 № 15.

Ответ 3

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

Ответ 4

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

Ответ 5

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

Обычно я делаю что-то вроде этого:

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

Ищете char в AccentString и заменив его для того же индекса в ConvertString

НТН

Ответ 6

В кодовой странице 1251 символы кодируются с помощью 2 байтов: один для базового char и один для варианта. Затем, когда вы кодируете обратно в 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-une-chaine-(proprement).aspx

Ответ 7

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

Ответ 8

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

Ответ 9

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

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

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

Ответ 10

Существует статья о CodeProject, которая выглядит хорошо.

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

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

Ответ 11

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

Ответ 12

Массив поиска - это, пожалуй, самый простой и быстрый способ выполнить это. Это один из способов, которым вы можете конвертировать, например, ASCII в EBCDIC.

Ответ 13

Верхние 128 символов не имеют стандартных значений. Они могут принимать разные интерпретации (кодовые страницы) в зависимости от языка пользователя.

Например, см. португальский против Французский канадский

Если вы не знаете кодовую страницу, ваш "перевод" иногда будет неправильным.

Если вы собираетесь взять определенную кодовую страницу (например, исходную кодовую страницу IBM), тогда будет работать массив переводов, но для истинных международных пользователей это будет неправильно.

Это одна из причин, по которой юникод пользуется более старой системой кодовых страниц.

Строго говоря, ASCII - всего 7 бит.

Ответ 14

Я использую эту функцию для фиксации переменной с акцентами для перехода к мыльной функции из VB6:

Function FixAccents(ByVal Valor As String) As String

    Dim x As Long
    Valor = Replace(Valor, Chr$(38), "&#" & 38 & ";")

    For x = 127 To 255
        Valor = Replace(Valor, Chr$(x), "&#" & x & ";")
    Next

    FixAccents = Valor

End Function

И внутри функции мыла я делаю это (для переменной Filename):

FileName = HttpContext.Current.Server.HtmlDecode(FileName)

Ответ 15

Попробуйте программу uni2ascii.