Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
python和ruby中的不同编码_Python_Ruby_Encoding_Ord - Fatal编程技术网

python和ruby中的不同编码

python和ruby中的不同编码,python,ruby,encoding,ord,Python,Ruby,Encoding,Ord,我试图在Python中模拟Rubys.bytesize字符串函数。但是,我对某些字符有问题,例如“'” 红宝石色 "‘".bytesize returns 3 "‘".bytes returns [226, 128, 152] 用Python ord("‘") returns 8216 len(ord("‘")) returns 1 这两种语言的编码有什么不同?这与提供类似对比结果的不同在线转换器进一步混淆。例如-生成与Ruby相同的结果,而生成与Python相同的结果。如果您处理的是UTF

我试图在Python中模拟Rubys.bytesize字符串函数。但是,我对某些字符有问题,例如“'”

红宝石色

"‘".bytesize returns 3
"‘".bytes returns [226, 128, 152]
用Python

ord("‘") returns 8216
len(ord("‘")) returns 1

这两种语言的编码有什么不同?这与提供类似对比结果的不同在线转换器进一步混淆。例如-生成与Ruby相同的结果,而生成与Python相同的结果。

如果您处理的是UTF-8字符串,请忽略字节

将返回代码点数组,返回UTF-8字符串的长度:

"‘".codepoints #⇒ [8216]
"‘".length     #⇒ 1
提供对Graphmas的低级访问

"‘".unpack "U+"

无论您是否仍希望访问字节,您可以:

"‘".unpack "C*"
#⇒ [226, 128, 152]
要在python中获取UTF-8符号的字节,可以使用
字节

>>> chars = bytes("‘".encode("utf8"))
>>> chars
#⇒ b'\xe2\x80\x98'
>>> len(chars)
#⇒ 3

假设您有两个UTF-8字符串

Python 3:

>>> s1
'è'
>>> s2
'è'
和Ruby:

> s1
=> "è"
> s2
=> "è"
虽然这些字符串看起来都一样,但它们不是:

>>> s1==s2
False

> s1==s2
=> false
这是因为虽然它们是相同的,但实际上是两个不同的字节字符串:

>>> [[s, len(s), list(s)] for s in (s1,s2)]
[['è', 1, ['è']], ['è', 2, ['e', '̀']]]
> [s1,s2].map {|s| [s, s.length, s.each_char.to_a]}
=> [["è", 1, ["è"]], ["è", 2, ["e", "̀"]]] 
正如你所看到的,有多种方法组成一个单一的字形,或者我们称之为字符。如果您在
s2
中有组合字符,如
“̀”
,则字符串的长度(按字节计)将不同于您预期的长度:

> s1.length==s2.length
=> false
在Ruby中,您可以使用
\X
正则表达式扫描组成单个图形的字节或字节组:

> s2.scan(/\X/)
=> ["è"]
> s2.unicode_normalize.length==s1.length
=> true
那么它们的逻辑长度将相同:

> s1.scan(/\X/).length==s2.scan(/\X/).length
=> true
或者,规范化字符串:

您还可以使用Ruby中的s2字符串将两个字节组合成一个等效的grapheme:

> s2.scan(/\X/)
=> ["è"]
> s2.unicode_normalize.length==s1.length
=> true
在Python中,您可以使用
unicodedate
来规范化:

>>> import unicodedata
>>> unicodedata.normalize('NFC', s2) == s1
True
>>> len(unicodedata.normalize('NFC', s2)) == len(s1)
True
或者安装并使用支持
\X
的。(模块不支持
\X

如果您真的希望在Python中采用与Ruby相同的逐字节方法,您可以:

>>> [int(e) for e in bytes("‘".encode('utf-8'))]
[226, 128, 152]
> "‘".bytes
=> [226, 128, 152]
但我不知道你打算用它做什么

或者,如果您想要相同的
ord
值:

>>> ord("‘")
8216
> "‘".ord
=> 8216

所以在Ruby中,当“'.”bytes#=>[226,128,152]这实际上返回了什么,它获取字节的目的是什么编码?它获取字节的目的不是单字节编码UTF-8。我如何在Python中复制这种效果?编辑:别看你的最新版本,它工作得很好,谢谢!如果要在python中复制此行为,请使用
bytes
将字符串作为参数传递。我想不出有什么理由这么做,除了非常低级的二进制传输,比如TCP级协议的实现,但我敢打赌这不是你想要实现的。我建议你从阅读一般的字符串编码开始。