【问题标题】:Why is indexing of UTF8 strings discouraged in Julia?为什么在 Julia 中不鼓励对 UTF8 字符串进行索引?
【发布时间】:2016-02-02 16:24:09
【问题描述】:

Julia 的介绍性指南 Learn Julia in Y Minutes 不鼓励用户索引 UTF8 字符串:

# Some strings can be indexed like an array of characters
"This is a string"[1] # => 'T' # Julia indexes from 1
# However, this is will not work well for UTF8 strings,
# so iterating over strings is recommended (map, for loops, etc).

为什么不鼓励对此类字符串进行迭代?这种替代字符串类型的结构具体是什么使索引容易出错?这是 Julia 特有的陷阱,还是扩展到所有支持 UTF8 字符串的语言?

【问题讨论】:

  • 由于 UTF-8 是 Unicode 的多字节编码,因此索引到 UTF-8 字符串或获取长度(以字符而不是代码单元为单位)是 O(n) (其中 n 是字符串的大小)操作。如果你需要经常做这样的事情,你最好使用 UTF32String,并根据需要转换为/从 UTF8。这不是 Julia 特有的陷阱,但是像 Python 3 这样的一些语言可以为 Unicode 字符串选择最佳的内部表示,根据字符串的不同,索引仍然是 O(1)。
  • @ScottJones 感谢您的提示。 UTF32String(类似于 C++ 中的std::wstring)是我真正需要的。

标签: string utf-8 julia


【解决方案1】:

因为在 UTF8 中,字符并不总是以单个字节编码。

以德语字符串böse(邪恶)为例。 该字符串在 UTF8 编码中的字节数为:

0x62 0xC3 0xB6 0x73 0x65
b    ö         s    e

如您所见,变音符号 ö 需要 2 个字节。

现在如果你直接索引这个 UTF8 编码的字符串 "böse"[4] 会给你s而不是e

但是,您可以在 julia 中将字符串用作可迭代对象:

julia> for c in "böse"
           println(c)
       end
b
ö
s
e

既然你问过,不,UTF8 字符串的直接字节索引问题并不是 Julia 特有的。

推荐阅读:
http://docs.julialang.org/en/release-0.4/manual/strings/#unicode-and-utf-8

【讨论】:

  • 您也可以使用 chr2ind 进行迭代,它将字节索引转换为字符索引:for i in 1:length(s); c = chr2ind(s, i); println(s[c]); end
  • @amrods 你可以使用graphemes 函数:collect(graphemes("böse")) 返回["b", "ö", "s", "e"]
  • 好点 stackoverflow.com/users/2374329/ismael-venegas-castelló 对于很多用例,使用字形确实是最好的选择,看看 Swift 2.0 的字符串处理,其中字形是您通常使用的,而不是代码点或代码单元。
【解决方案2】:

为了扩展 Scott Jones 的评论,Julia 实际上还提供了与 C++ 中的 std::wstring 类似的固定宽度字符串,这样可以方便地进行索引。他们现在在https://github.com/JuliaStrings/LegacyStrings.jl 需要先用Pkg.add("LegacyStrings") 安装软件包。

UTF32String 将是大多数用例的最佳选择。从普通字符串构造UTF32Strings2 = utf32(s)

【讨论】:

    猜你喜欢
    • 2012-10-03
    • 2015-02-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-24
    • 2015-09-05
    • 1970-01-01
    • 2012-12-16
    相关资源
    最近更新 更多