如何将8位字符转换为7位字符?(例如,将Ü转换为U)

26
我正在寻找伪代码或示例代码,将高位ASCII字符(例如扩展ASCII 154表示的Ü)转换为普通ASCII字符U(ASCII 85)。
我的初步猜测是,由于只有大约25个ASCII字符类似于7位ASCII字符,因此需要使用一个翻译数组。
如果您能想到其他任何方法,请告诉我。

请查看下面 sinelaw 的答案,这是一个非常好的 .NET 解决方案。 - Dave
15个回答

40

对于.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

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


11

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


3
即使这很简单,如果在全大写单词中使用,Ü 也会变成 UE。 - Felix Dombek
还有一些情况需要使用7位字符集,例如SMTP内容传输编码 - en.wikipedia.org/wiki/MIME#Content-Transfer-Encoding。另外,如果您因为SMTP问题查看此帖子,请查看您的SMTP客户端/库的UUEncoding功能。 - Aaron Newton

6

我认为你不能这样做。

我通常会这样做:

AccentString = 'ÀÂÄÉÈÊ[以及所有其他字符]'
ConvertString = 'AAAEEE[以及所有其他字符]'

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

希望对你有所帮助。


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

该文章介绍了如何正确地从字符串中移除重音符号。这在 IT 技术中经常用到,比如当你需要将字符串用作文件名或 URL 时。通过使用 C# 中的特定类和方法,可以轻松地实现这一目标。

5

如通过unexist提出的建议: "iconv"函数存在于几乎所有编程语言中,可处理所有奇怪的转换,并具有特殊选项,尝试使用近似值将目标集中缺失的字符进行转换。

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

否则,您总会遇到角落案例:8位输入使用不同的代码页和不同的字符集(因此根本无法与您的转换表一起使用),忘记映射一个最后的愚蠢重音字符(您映射了所有重/轻音符号,但忘记了映射捷克符号或北欧'°'等)等等。

当然,如果您想将解决方案应用于小型特定问题(为音乐收藏创建文件系统友好的文件名),则查找数组是正确的方法(对于每个超过128的代码号码映射为128下面的近似值,如JeeBee所建议的;或者vIceBerg提出的源/目标对取决于您选择的语言中已有哪些替换函数),因为它可以快速地组合并快速检查缺少的元素。


1

我认为你已经掌握了它。一个128字节长的字节数组,由char&127索引,包含8位比特字符的匹配7位字符。


1
嗯,为什么不使用iconv更改字符串的编码呢?

1

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

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

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

如果您要假设某个代码页(例如原始IBM代码页),那么翻译数组就会有效,但对于真正的国际用户来说,它将经常出错。

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

严格来说,ASCII仅有7位。


1

有一篇关于CodeProject的文章看起来不错。

另外,使用代码页1251进行转换引起了我的兴趣(请参见其他答案)。

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接