如何将Unicode字符转换为其ASCII等效字符

14

问题如下:

我正在从一个遗留的ACCESS数据库中获取信息,使用C#。 .NET将数据库内容(在这个问题中是字符串)转换为Unicode,然后将其交给我。

如何将这个Unicode字符串转换回它的ASCII等效字符?


编辑
Unicode char 710 确实是 MODIFIER LETTER CIRCUMFLEX ACCENT(修改符号^)。以下是更精确的问题描述:

-> 数据库中插入了一个(扩展)ASCII字符ê(扩展ASCII 136)。
-> Access或.NET中的读取组件将其转换为U+02C6 U+0065(MODIFIER LETTER CIRCUMFLEX ACCENT + LATIN SMALL LETTER E)
-> 我需要(扩展)ASCII字符136。


以下是我尝试过的方法(现在我知道为什么这不起作用...):

string myInput = Convert.ToString(Convert.ToChar(710));
byte[] asBytes = Encoding.ASCII.GetBytes(myInput);

但这并不会导致94,而是一个值为63的字节…
这里有一个新的尝试,但它仍然无效:

byte[] bytes = Encoding.ASCII.GetBytes("ê");


解决方案
感谢csgerobzlm指出了正确的方向,我在这里解决了问题。


1
术语“扩展ASCII”很令人困惑。如果您的输入数据确实是ASCII,则不存在ë或“字符编号136”。更有可能的是,您的数据包含ASCII无法表示的字符,例如可以由遗留的8位编码(如Windows-1252)表示的国际数据。 - bzlm
我知道,这个主题有一整篇维基百科文章。 - Huppie
你应该将解决方案作为答案发布,而不是在问题中,这样我们才能对其进行投票。 - Thomas Danecker
5个回答

11

好的,让我们详细说明一下。csgerobzlm都指出了正确的方向。

由于blzm的回复,我在维基百科上查找了Windows-1252页面,并发现它被称为代码页。Code page的维基百科文章如下所述:

这些“extended character sets”没有正式的标准;IBM仅将变体称为代码页,就像对EBCDIC编码的变体一样。

这使我想到了代码页437:

在ASCII兼容的代码页中,较低的128个字符保持其标准的US-ASCII值,而不同的页(或字符集)可以在较高的128个字符中提供。例如,面向北美市场的DOS计算机使用code page 437,其中包括法语、德语和其他一些欧洲语言所需的重音字符,以及一些图形线条字符。

因此,代码页437是我所说的“扩展ASCII”的代码页,它将ê作为字符136,因此我查找了一些其他字符,它们看起来也是正确的。

csgero提供了使用Encoding.GetEncoding()的提示,我使用它创建了以下语句来解决我的问题:

byte[] bytes = Encoding.GetEncoding(437).GetBytes("ê");

5
请参考Unicode规范化主题,特别是两种等价形式:标准规范化和兼容规范化-http://en.wikipedia.org/wiki/Unicode_normalization。在.NET String实例上,调用Normalize方法,传递NormalizationForm.FormD或NormalizationForm.FormKD,对应于标准规范化和兼容规范化分解形式。例如,在字符串"êwś"上调用此方法,将生成字符串"e^ws'"。您也可以执行反向操作,通过调用Normalize(NormalizationForm.FormC)或Normalize(NormalizationForm.FormKC)将类似"e^"的字符串转换为"ê"。 - Triynko

4

在这里您不能使用默认的ASCII编码(Encoding.ASCII),而是必须使用适当的代码页创建编码,使用Encoding.GetEncoding(...)。您可以尝试使用代码页1252,它是ISO 8859-1的超集。


像这样:byte[] bytes = Encoding.GetEncoding(437).GetBytes("ê"); - Huppie

2
ASCII并未定义ê;数字136来自于8位编码如Windows-1252中circumflex的数字。请确认在这种情况下Access数据库中实际存储了小写字母e和带圆形抑音符号的字符(ê)。也许U+02C6 U+0065是转换错误的结果,输入实际上是一个带有圆形抑音符号的e后面跟着一个字符,或者其他情况。也许你的Access数据库数据已经损坏,因为指定的编码与内容不匹配,在这种情况下,.NET客户端可能会错误地解析数据(使用错误的解码器)。如果此错误确实是在从数据库读取期间引入的,请提供一些代码或配置设置以帮助解决问题。在代码页437中,编号136是一个带有圆形抑音符号的小写字母e。

谢谢!你的提示帮了很多忙,实际上是代码页437(MS-DOS)。使用 Encoding.GetEncoding(437) 就可以解决问题了。 - Huppie

0

嗯...我不确定你指的是哪个字符。插入符号(“^”,CIRCUMFLEX ACCENT)在ASCII和Unicode(U+005E)中有相同的代码。

/编辑:该死,我的错。710(U+02C6)实际上是MODIFIER LETTER CIRCUMFLEX ACCENT。不幸的是,这个字符根本不属于ASCII。它可能看起来像普通的插入符号,但它是一个不同的字符。简单的转换在这里没有用。我不确定.NET在从Unicode转换时是否支持类似字符的映射。不过值得调查一下。


OJ:这与UTF-8有什么关系? - C. K. Young
@OJ,我知道这一点。然而,字符的代码点在所有Unicode编码中都是相同的。 - Konrad Rudolph
@Chris:在Konrad的原始帖子中,他谈到了UTF8而不是Unicode。 - OJ.
你说得对,确实是修饰符带抑扬符号,看看我的修改。 - Huppie

0

数值63代表问号,也被称为“ASCII中无法显示该字符”。


所以,你正在找出我的问题。问题是我该如何做到这一点,我知道我尝试的方法不起作用。 - Huppie

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