グラフィムクラスターをGo言語で扱う

2021年05月02日

Go言語

人間が文字として考える最小単位であるグラフィムクラスターについて調べました。

Go言語でグラフィムクラスターを扱って文字列反転する処理を記載しています。

グラフィムクラスター(書記素クラスター)とは

他の分野ではわかりませんが、Unicode においては 「人間が文字として考える 1 つ以上の Unicode コードポイント」という意味のようです。 参考

通常 1 つの Unicode コードポイントに人間が 1 文字として数える文字が対応付けされていますが例外もあります。 例えば、ハングルの 하\ud558\u0301 のように 2 つの Unicode コードポイントで表現されますが、人間が見る場合 하 は 1 文字として数えたいですよね。

このような例外を扱うことができるのがグラフィムクラスターです。

Go 言語でグラフィムクラスターを扱う

今回は Go 言語でグラフィムクラスターを扱う手段を調べました。 golang.org/x/text/unicode/norm を使って、文字列反転の処理を書くとこんな感じです。

単純に rune 単位で処理すると出力が意図した通りになりませんが、グラフィムクラスターとして処理するとしっかり反転しています。

package main

import (
	"fmt"
	"golang.org/x/text/unicode/norm"
)

func reverseUgly(s string) string {
	runes := []rune(s)
	for i, j := 0, len(runes)-1; i < j; i, j = i+1, j-1 {
		runes[i], runes[j] = runes[j], runes[i]
	}
	return string(runes)
}

func reverseGrapheme(s string) string {
	iter := norm.Iter{}
	iter.InitString(norm.NFD, s)

	rev := ""
	for !iter.Done() {
		next := iter.Next()
		rev = string(next) + rev
	}
	return rev
}

func main() {
	s := norm.NFD.String("하세")
	fmt.Println(reverseUgly(s))
	fmt.Println(reverseGrapheme(s))
}
// 出力
ᅦ사ᄒ
세하