Edited at

Rubyを使ってタイ語の表示文字単位で文字列を区切る

More than 5 years have passed since last update.

タイ語の"พี่ชาย" (日本語で兄の意味)は表示上は4文字ですが、最初の文字"พี่"が3つのUCS("e1e", "e35", "e48")から構成されており、単純にsplit(//)をしただけでは6文字に分解されてしまいます。

いいやり方が思いつかなかったのでいったん全てばらしたものを再度走査して単独で成立しない文字を直前のものにくっつけて処理しました。

もっと効率的な書き方・Rubyらしい書き方があればご教授ください。


disp_ucs_thai.rb

#!/usr/bin/env ruby

# -*- coding: utf-8 -*-

ca = "พี่ชาย".split(//) # ["e1e", "e35", "e48", "e0a", "e32", "e22"]
ca_length = ca.length

i = 0
while i < (ca_length - 1)
case ca[i+1]
when "\u0e31", "\u0e34".."\u0e3A", "\u0e47".."\u0e4e" then
ca[i] = ca[i] + ca[i+1]
ca.delete_at(i+1)
ca_length = ca.length
else
i = i+1
end
end

ca.each do |ch|
clist = ch.each_codepoint.map {|cp| "U+" + cp.to_s(16)}
puts ch + " [#{clist.join(' ')}]"
end


$ ruby disp_ucs.rb

พี่ [U+e1e U+e35 U+e48]
[U+e0a]
[U+e32]
[U+e22]

参考 ⇒ 複雑なテキスト配置 - Wikipedia