24

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

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

让我知道你是否还能想到别的。

4

15 回答 15

38

对于 .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 Annex #15

于 2012-04-05T22:29:30.353 回答
17

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

于 2008-09-26T16:33:24.367 回答
11

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

于 2008-09-26T16:43:14.123 回答
6

我认为你不能。

我通常会这样做:

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

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

高温高压

于 2008-09-26T16:08:43.817 回答
6

在代码页 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

于 2008-09-29T09:51:31.030 回答
5

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

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

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

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

于 2008-09-26T16:41:24.707 回答
1

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

于 2008-09-26T16:08:49.480 回答
1

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

于 2008-09-26T16:15:52.147 回答
1

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

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

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

于 2008-09-26T16:24:22.780 回答
1

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

例如,请参阅 葡萄牙语加拿大法语

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

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

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

严格来说,ASCII 只有 7 位。

于 2008-09-26T16:36:47.917 回答
1

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

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

我不喜欢转换表,因为 Unicode 中的字符数很大,你很容易错过。

于 2008-10-08T16:03:34.417 回答
0

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

于 2008-09-26T16:07:02.107 回答
0

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

于 2008-09-26T16:13:39.017 回答
0

我使用这个函数来修复一个带有重音符号的变量,以便从 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)
于 2009-06-07T17:07:18.907 回答
-1

试试uni2ascii程序。

于 2010-03-09T05:32:56.227 回答