【发布时间】:2013-07-27 08:47:58
【问题描述】:
我有问题。 Unicode 2019 是这个字符: ’
这是一个正确的单引号。 它被编码为 UTF8。 但我担心它会被双重编码。
>>> u'\u2019'.encode('utf-8')
'\xe2\x80\x99'
>>> u'\xe2\x80\x99'.encode('utf-8')
'\xc3\xa2\xc2\x80\xc2\x99'
>>> u'\xc3\xa2\xc2\x80\xc2\x99'.encode('utf-8')
'\xc3\x83\xc2\xa2\xc3\x82\xc2\x80\xc3\x82\xc2\x99'
>>> print(u'\u2019')
’
>>> print('\xe2\x80\x99')
’
>>> print('\xc3\xa2\xc2\x80\xc2\x99')
’
>>> '\xc3\xa2\xc2\x80\xc2\x99'.decode('utf-8')
u'\xe2\x80\x99'
>>> '\xe2\x80\x99'.decode('utf-8')
u'\u2019'
This is the principle used above.
如何在 C# 中处理粗体部分?
如何获取 UTF8 编码的字符串,转换为字节数组,将其转换为字符串,然后再次解码?
我试过this的方法,但是输出的结果不适合ISO-8859-1,看来……
string firstLevel = "’";
byte[] decodedBytes = Encoding.UTF8.GetBytes(firstLevel);
Console.WriteLine(Encoding.UTF8.GetChars(decodedBytes));
// ’
Console.WriteLine(decodeUTF8String(firstLevel));
//â�,��"�
//I was hoping for this:
//’
了解更新:
Jon 帮助我解决了最基本的问题:从“’”到“’”,然后再到“'”但我想尊重他回答的核心建议:
- 了解正在发生的事情
- 修复原罪
我努力排在第一位。
编码/解码
我对这些术语感到非常困惑。 我将它们与加密/解密之类的术语混淆了,仅仅是因为“En...”和“De...” 我忘记了他们翻译的内容,以及他们翻译的内容。 我混淆了这些起点和终点;它是否与十六进制、字符实体、代码点和字符映射等其他模糊术语有关。
我想在基本层面上解决定义。 这个问题的上下文中的编码和解码是:
- 解码
- 对应于 C# {Encoding}。'''GetString'''(bytesArray)
- 对应Python stringObject.'''decode'''({Encoding})
- 根据称为“编码”的某种转换方案,将字节作为输入,并转换为字符串表示形式作为输出,由上面的 {Encoding} 表示。
- 字节 -> 字符串
- 编码
- 对应于 C# {Encoding}。'''GetBytes'''(stringObject)
- 对应 Python stringObject.'''encode'''({Encoding})
- 解码的反面。
- 字符串 -> 字节(Python 除外)
Python 中的字节与字符串
所以 Encode 和 Decode 带我们在字节和字符串之间来回切换。
虽然 Python 帮助我了解出了什么问题,但它也可能会混淆我对编码/解码“基础知识”的理解。 乔恩说:
可惜Python在很大程度上隐藏了【二进制数据和文本数据的区别】
我认为这就是 PEP 在it says: 时的意思
Python 的当前字符串对象被重载。它们用于保存字符序列和字节序列。这种重载目的会导致混乱和错误。
Python 3.* 不会以这种方式重载字符串。:
Python 2.7
>>> #Encoding example. As a generalization, "Encoding" produce bytes.
>>> #In Python 2.7, strings are overloaded to serve as bytes
>>> type(u'\u2019'.encode('utf-8'))
<type 'str'>
Python 3.*
>>> #In Python 3.*, bytes and strings are distinct
>>> type('\u2019'.encode('utf-8'))
<class 'bytes'>
Python 2 和 3 之间的另一个重要(相关)区别是它们的默认编码:
>>>import sys
>>>sys.getdefaultencoding()
Python 2
'ascii'
Python 3
'utf-8'
虽然 Python 2 说“ascii”,但我认为它的意思是 specific type of ASCII;
- “不是”是指 ISO-8859-1,它支持范围 (256),这是 Jon 用来解码的(下文讨论)
- 表示ASCII,最简单的变种,只有range(128)
虽然 Python 3 不再将字符串作为字节和字符串重载,但解释器仍然可以很容易地忽略正在发生的事情并在类型之间移动。即
- 只需在 Python 2.* 中的字符串前加一个 'u',它就是一个 Unicode 文字
- 只需在 Python 3.* 中的字符串前加一个 'b',它就是一个字节字面量
编码和C
Jon 指出 C# 使用 UTF-16 来更正我上面的“UTF-8 编码字符串”注释;
每个字符串实际上都是 UTF-16。 我的理解是:如果C#有一个字符串对象“s”,那么计算机内存中其实有UTF-16 map.中那个字符对应的字节,也就是(包括byte-order-mark??)feff0073。
他还在我要求的破解方法中使用了 ISO-8859-1。 我不确定为什么。 我现在头很痛,等我有看法再回来。
我会回到这篇文章。我希望我解释得当。我会把它做成一个 Wiki 吗?
【问题讨论】:
-
.NET 中不存在“UTF-8 编码字符串”之类的东西。 每个 字符串实际上是 UTF-16。如果您可能可以,您应该修复表现不佳的代码(将二进制数据编码为文本)。
-
谢谢。我需要对编码有更深入的了解。我将重读 Spolsky 等人的著作。是否可以在 C# 中从“’”转为“’”?不幸的是,我无法修复原罪。