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

StackOverflow https://stackoverflow.com/questions/140422

  •  02-07-2019
  •  | 
  •  

Вопрос

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

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

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

Это было полезно?

Решение

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

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

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

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

Другие советы

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

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

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

Дополнительные сведения о формах нормализации Юникода см. Приложение Юникода № 15.

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

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

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

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

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

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

ХТХ

На кодовой странице 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-une-chaine-(proprement).aspx

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

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

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

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

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

Есть статья о КодПроект выглядит хорошо.

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

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

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

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

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

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

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

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

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

Строго говоря, ASCII имеет длину всего 7 бит.

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

Я использую эту функцию, чтобы исправить переменную с акцентами для передачи в мыльную функцию из 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)
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top