【问题标题】:How to iterate over grapheme clusters in Crystal?如何在 Crystal 中迭代字素簇?
【发布时间】:2021-04-29 12:45:40
【问题描述】:

Unicode 标准将grapheme cluster 定义为“用户感知字符”的算法近似值。字素簇或多或少对应于人们认为的文本中的单个“字符”。因此,能够将字符串作为字素簇的序列进行操作是编程中自然而重要的要求。

最好的通用字素簇定义是扩展字素簇;还有其他用于特定本地化用途的字素集群算法(定制的字素集群)。

在 Crystal 中,我如何将 String 迭代(或以其他方式操作)作为一系列字素簇?

【问题讨论】:

    标签: crystal-lang grapheme grapheme-cluster


    【解决方案1】:

    此答案基于Crystal forum 中的一个线程。

    从 1.0.0 开始,Crystal 没有内置的方法来执行此操作(很遗憾)。

    但是,Crystal 中的 regex 引擎可以,\X 模式匹配单个扩展字素簇:

    "\u0067\u0308\u1100\u1161\u11A8".scan(/\X/) do |match|
      grapheme = match[0]
      puts grapheme
    end
    
    # Output:
    # g̈
    # 각
    

    Run it online

    您可以将其封装在更好的 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]
    

    Run it online

    【讨论】:

      猜你喜欢
      • 2020-03-05
      • 2022-08-21
      • 2019-06-26
      • 2013-08-03
      • 2016-12-24
      • 1970-01-01
      • 1970-01-01
      • 2021-01-21
      • 1970-01-01
      相关资源
      最近更新 更多