[102, 111, 111, 246] 是否有一个内置的方法去另一个-6ren">
gpt4 book ai didi

ruby 1.9 - `string.codepoints.to_a` 最简单的逆运算是什么?

转载 作者:数据小太阳 更新时间:2023-10-29 06:57:59 25 4
gpt4 key购买 nike

在 ruby​​ 1.9.3 中,我可以获得字符串的代码点:

> "foo\u00f6".codepoints.to_a
=> [102, 111, 111, 246]

是否有一个内置的方法去另一个方向,即从整数数组到字符串?

我知道:

# not acceptable; only works with UTF-8
[102, 111, 111, 246].pack("U*")

# works, but not very elegant
[102, 111, 111, 246].inject('') {|s, cp| s << cp }

# concise, but I need to unshift that pesky empty string to "prime" the inject call
['', 102, 111, 111, 246].inject(:<<)

更新(对尼克拉斯回答的回应)

有趣的讨论。pack("U*") 始终返回 UTF-8 字符串,而 inject 版本返回文件源编码中的字符串。

#!/usr/bin/env ruby
# encoding: iso-8859-1

p [102, 111, 111, 246].inject('', :<<).encoding
p [102, 111, 111, 246].pack("U*").encoding
# this raises an Encoding::CompatibilityError
[102, 111, 111, 246].pack("U*") =~ /\xf6/

对我来说,inject 调用返回一个 ISO-8859-1 字符串,而 pack 返回一个 UTF-8。为了防止错误,我可以使用 pack("U*").encode(__ENCODING__) 但这让我做了额外的工作。

更新 2

显然,根据字符串的编码,String#<< 并不总是正确附加。所以看起来 pack 仍然是最好的选择。

[225].inject(''.encode('utf-16be'), :<<)  # fails miserably
[225].pack("U*").encode('utf-16be') # works

最佳答案

您自己尝试的最明显的改编是

[102, 111, 111, 246].inject('', :<<)

然而,这不是一个好的解决方案,因为它只有在初始空字符串文字具有能够容纳整个 Unicode 字符范围的编码时才有效。以下失败:

#!/usr/bin/env ruby
# encoding: iso-8859-1
p "\u{1234}".codepoints.to_a.inject('', :<<)

所以我实际上会推荐

codepoints.pack("U*")

我不知道“仅适用于 UTF-8”是什么意思。它创建了一个 UTF-8 编码的 Ruby 字符串,但是 UTF-8 可以容纳整个 Unicode 字符范围,那么问题是什么?观察:

irb(main):010:0> s = [0x33333, 0x1ffff].pack("U*")
=> "\u{33333}\u{1FFFF}"
irb(main):011:0> s.encoding
=> #<Encoding:UTF-8>
irb(main):012:0> [0x33333, 0x1ffff].pack("U*") == [0x33333, 0x1ffff].inject('', :<<)
=> true

关于ruby 1.9 - `string.codepoints.to_a` 最简单的逆运算是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10304754/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com