【问题标题】:How do I translate 8bit characters into 7bit characters? (i.e. Ü to U)如何将 8 位字符转换为 7 位字符? (即 Ü 到 U)
【发布时间】:2010-09-13 12:22:40
【问题描述】:

我正在寻找伪代码或示例代码,以将高位 ascii 字符(例如,扩展 ascii 154 的 Ü)转换为 U(即 ascii 85)。

我最初的猜测是,由于只有大约 25 个 ascii 字符类似于 7bit ascii 字符,因此必须使用翻译数组。

如果你还能想到什么,请告诉我。

【问题讨论】:

  • 请参阅下面的sinelaw's answer,了解 .NET 中的一个非常棒的解决方案。

标签: ascii


【解决方案1】:

对于 .NET 用户,article in CodeProject(感谢GvS's tip)确实比我迄今为止看到的任何其他问题都更正确地回答了这个问题。

但是那篇文章中的代码(在解决方案 #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 Annex #15

【讨论】:

    【解决方案2】:

    大多数语言都有用标准 ASCII 替换重音字符的标准方法,但这取决于语言,并且通常涉及用两个 ASCII 字符替换单个重音字符。例如在德语中 ü 变成 ue。因此,如果您想正确处理自然语言,它比您想象的要复杂得多。

    【讨论】:

      【解决方案3】:

      将 Ü 转换为 U 真的是您想要做的吗?我不知道其他语言,但在德语中 Ü 会变成 Ue,ö 会变成 oe,等等。

      【讨论】:

      • 甚至没有那么简单,如果用在全大写单词中,Ü会变成UE
      • 还有某些情况下必须使用 7 位字符集,例如 SMTP Content-Transfer-Encoding - en.wikipedia.org/wiki/MIME#Content-Transfer-Encoding。附带说明一下,如果您因为 SMTP 问题而查看这篇文章,请查看您的 SMTP 客户端/库的 UUEncoding 功能。
      【解决方案4】:

      我认为你做不到。

      我通常会这样做:

      AccentString = 'ÀÂÄÉÈÊ[和所有其他]'
      ConvertString = 'AAAEEE[和所有其他]'

      在 AccentString 中查找字符并将其替换为 ConvertString 中的相同索引

      HTH

      【讨论】:

        【解决方案5】:

        在代码页 1251 中,字符用 2 个字节编码:一个用于基本字符,一个用于变体。然后,当您重新编码为 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

        【讨论】:

          【解决方案6】:

          确实如 unexist 所提议的那样: “iconv”函数的存在是为了为您处理所有奇怪的转换,几乎在所有编程语言中都可用,并且有一个特殊选项,它尝试用近似值转换目标集中缺少的字符。

          使用 iconv 将输入的 UTF-8 字符串简单地转换为 7 位 ASCII。

          否则,您总是会遇到极端情况:使用具有不同字符集的不同代码页的 8 位输入(因此根本无法使用您的转换表),忘记映射最后一个愚蠢的重音字符(您映射所有重音/重音,但忘记映射捷克语 caron 或北欧 '°') 等。

          当然,如果您想将解决方案应用于一个小的特定问题(为您的音乐收藏创建文件系统友好的文件名),那么查找数组是可行的方法(对于上述每个代码编号的数组) 128 映射了 JeeBee 提出的低于 128 的近似值,或者 viceBerg 提出的源/目标对,具体取决于您选择的语言中已经可用的替换函数),因为它可以快速组合在一起并快速检查缺失的元素。

          【讨论】:

            【解决方案7】:

            我想你似乎已经成功了。一个 128 字节长的字节数组,以 char&127 为索引,包含与 8 位位字符匹配的 7 位字符。

            【讨论】:

              【解决方案8】:

              嗯,为什么不直接用 iconv 改变字符串的编码呢?

              【讨论】:

                【解决方案9】:

                前 128 个字符没有标准含义。根据用户的语言,它们可以采用不同的解释(代码页)。

                例如,请参阅 Portuguese 相对 French Canadian

                除非您知道代码页,否则您的“翻译”有时会出错。

                如果您要假设某个代码页(例如原始 IBM 代码页),那么翻译数组将起作用,但对于真正的国际用户来说,这将是很多错误的。

                这就是为什么 unicode 比旧的代码页系统更受青睐的原因之一。

                严格来说,ASCII只有7位。

                【讨论】:

                  【解决方案10】:

                  这实际上取决于源字符串的性质。如果您知道字符串的编码,并且知道它是 8 位编码(例如 ISO Latin 1 或类似编码),那么一个简单的静态数组就足够了:

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

                  另一方面,如果您有不同的编码,或者如果您使用的是 UTF-8 编码的字符串,您可能会发现 ICU 库中的函数非常有用。

                  【讨论】:

                    【解决方案11】:

                    CodeProject上有一篇文章,看起来不错。

                    我也对使用代码页 1251 的转换感兴趣(请参阅其他答案)。

                    我不喜欢转换表,因为 Unicode 中的字符数量很大,很容易漏掉一个。

                    【讨论】:

                      【解决方案12】:

                      我想你已经把它钉在了头上。鉴于您的域有限,转换数组或哈希是您的最佳选择。创建任何复杂的东西来尝试自动执行它是没有意义的。

                      【讨论】:

                        【解决方案13】:

                        查找数组可能是完成此任务的最简单和最快的方法。这是一种可以将 ASCII 转换为 EBCDIC 的方法。

                        【讨论】:

                          【解决方案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
                          

                          在soap函数中我这样做(对于变量文件名):

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

                          【讨论】:

                            【解决方案15】:

                            试试uni2ascii 程序。

                            【讨论】:

                              猜你喜欢
                              • 1970-01-01
                              • 2013-08-20
                              • 2016-04-12
                              • 2010-09-12
                              • 1970-01-01
                              • 2017-06-03
                              • 2016-06-08
                              • 1970-01-01
                              • 2016-02-25
                              相关资源
                              最近更新 更多