Unicode 标准将字素簇定义为“用户感知字符”的算法近似。字素簇或多或少对应于人们认为的文本中的单个“字符”。因此,能够将字符串作为字素簇的序列进行操作是编程中自然而重要的要求。
最好的通用字素簇定义是扩展字素簇;还有其他用于特定本地化用途的字素集群算法(定制的字素集群)。
String
在 Crystal 中,我如何将 a作为一系列字素簇进行迭代(或以其他方式操作) ?
Unicode 标准将字素簇定义为“用户感知字符”的算法近似。字素簇或多或少对应于人们认为的文本中的单个“字符”。因此,能够将字符串作为字素簇的序列进行操作是编程中自然而重要的要求。
最好的通用字素簇定义是扩展字素簇;还有其他用于特定本地化用途的字素集群算法(定制的字素集群)。
String
在 Crystal 中,我如何将 a作为一系列字素簇进行迭代(或以其他方式操作) ?
此答案基于Crystal 论坛中的一个主题。
从 1.0.0 开始,Crystal 没有内置的方法来执行此操作(不幸的是)。
但是, Crystal 中的正则表达式引擎可以,其\X
模式匹配单个扩展字素簇:
"\u0067\u0308\u1100\u1161\u11A8".scan(/\X/) do |match|
grapheme = match[0]
puts grapheme
end
# Output:
# g̈
# 각
您可以将其包装在一个更好的 API 中,如下所示:
def each_grapheme(s : String, &)
s.scan(/\X/) do |match|
yield match[0]
end
end
def graphemes(s : String) : Array(String)
result = Array(String).new
each_grapheme(s) do |g|
result << g
end
return result
end
# Example from https://docs.swift.org/swift-book/LanguageGuide/StringsAndCharacters.html
s = "\u{E9}\u{65}\u{301}\u{D55C}\u{1112}\u{1161}\u{11AB}"
each_grapheme(s) do |g|
puts "#{g}\t#{g.codepoints}"
end
# Output:
# é [233]
# é [101, 769]
# 한 [54620]
# 한 [4370, 4449, 4523]