Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
文字ときどきRuby / Character and Ruby
Search
とみたまさひろ
December 09, 2023
Technology
0
360
文字ときどきRuby / Character and Ruby
とみたまさひろ
December 09, 2023
Tweet
Share
More Decks by とみたまさひろ
See All by とみたまさひろ
Ruby on Browser
tmtms
1
920
私のRSpecの書き方 / How I write RSpec
tmtms
4
1.2k
ショートカットと端末 / shortcut & terminal
tmtms
2
320
文字ときどきRuby / Character and Ruby (NSEG)
tmtms
2
1.5k
Linux用キーリマッパーを作る技術 / How to make Key Remapper
tmtms
0
320
MIMEヘッダエンコーディングは複雑すぎてつらい / MIME header encoding is hard
tmtms
3
1.4k
Net::SMTP
tmtms
1
260
MySQL Parameters の裏側 / MySQL Parameters backend
tmtms
1
400
MySQLユーザ会のこれまでとこれから / MyNA past and future
tmtms
0
72
Other Decks in Technology
See All in Technology
さらに高品質・高速化を目指すAI時代のテスト設計支援と、めざす先 / AI Test Lab vol.1
shift_evolve
0
190
AWSでRAGを作る法方
sonoda_mj
1
140
【基調講演】変える、今ここから ― IoTとAIで紡ぐ未来
soracom
PRO
0
320
DevIO2024_レガシー運用からの脱却 -クラウド活用の実践事例とベストプラクティス-
jun2882
0
210
Amazon FSx for NetApp ONTAPのパフォーマンスチューニング要素をまとめてみた #cm_odyssey #devio2024
non97
0
220
AOAI Dev Day - Opening Session
yoshidashingo
2
470
運用改善、不都合な真実 / 20240722-ssmjp-kaizen
opelab
17
8.4k
ここがすごいよ! AWS Systems Manager!
saichan11
0
1.8k
ギークの理想が7つ集まるエムスリーで夢を叶えよう - エムスリー株式会社
m3_engineering
1
260
ソフトウェアエンジニアリングの知見を活かして データ基盤をいい感じにする on Snowflake [MIERUNE BBQ #10]
mtpooh
2
150
Classmethod流のPlatform Engineering / classmethod-platform-engineering-devio2024
tomoki10
0
480
データベース研修 分析向けSQL入門【MIXI 24新卒技術研修】
mixi_engineers
PRO
0
110
Featured
See All Featured
Six Lessons from altMBA
skipperchong
24
3.2k
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
129
32k
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
224
21k
Designing the Hi-DPI Web
ddemaree
276
34k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
16
1.6k
Rebuilding a faster, lazier Slack
samanthasiow
78
8.5k
The Cult of Friendly URLs
andyhume
75
5.9k
Automating Front-end Workflow
addyosmani
1362
200k
Testing 201, or: Great Expectations
jmmastey
33
6.9k
Why You Should Never Use an ORM
jnunemaker
PRO
51
8.9k
What's new in Ruby 2.0
geeforr
338
31k
Build The Right Thing And Hit Your Dates
maggiecrowley
28
2.2k
Transcript
文字ときどきRuby nagano.rb #13 2023-12-09 とみたまさひろ 1
自己紹介 • とみたまさひろ • • https://twitter.com/tmtms https://blog.tmtms.net 2
これは同じ文字? 直 直 3
フォントが違うだけで同じ文字 直 U+76F4 日本語フォント 直 U+76F4 中国語フォント 4
これの違いと同じ 直 直 5
コンピュータで扱う文字は文字ごとに番号(コードポイント) が振られていてプログラムから見たときは同じコードポイ ントであれば同じ文字 6
Rubyでコードポイントを知る > '直'.ord.to_s(16) "76f4" > 'ほげ'.chars.map{_1.ord.to_s(16)} ["307b", "3052"] > 'ほげ'.unpack('U*').map{_1.to_s(16)}
["307b", "3052"] 7
これは同じ文字? 令 令 8
違う文字 令 U+4EE4 CJK統合漢字 令 U+F9A8 CJK互換漢字 9
正規化すれば同じ文字 String#unicode_normalize > '令'=='令' false > '令'=='令'.unicode_normalize true 10
正規化でこんなことも 使いようによっては便利 '0'.unicode_normalize(:nfkc) => '0' '①'.unicode_normalize(:nfkc) => '1' 'ア'.unicode_normalize(:nfkc) =>
'ア' 'パ'.unicode_normalize(:nfkc) => 'パ' '㌖'.unicode_normalize(:nfkc) => 'キロメートル' 11
これは同じ文字? 令 � 12
異体字 令 U+4EE4 � U+4EE4 U+E0102 13
基底文字に異体字セレクタを追加することで プレーンテキストでも文字の見た目を 指定することができる 14
異体字セレクタ � U+4EE4 U+E0102 ←これ U+E0100〜U+E01EF が異体字セレクタ 対応システムと対応フォントが必要 15
異体字セレクタ 異体字セレクタセレクタが便利 https://747.github.io/vsselector/#!/ja/908a 16
異体字セレクタ unicode_normalize では消えないので U+E0100〜U+E01EF を消す "\u4ee4\u{e0102}".gsub(/[\u{e0100}-\u{e01ef}]/, '') 17
「髙」と「﨑」 > '高' == '髙' false > '崎' == '﨑'
false 18
「髙」 Unicode では「髙」は「高」の異体字ではなく別の文字 別の文字なので異体字セレクタにもない SJIS(Windows-31J)でも別の文字 でも JIS では「髙」という文字は存在しない 「高」の異体字扱い 19
「髙」 > '髙'.encode('Windows-31J') "\x{FBFC}" > '髙'.encode('SJIS') # SJIS は Windows-31J
の別名 "\x{FBFC}" > '髙'.encode('Shift_JIS') # Shift_JIS と SJIS は異なる # `encode': U+9AD9 from UTF-8 to Shift_JIS # (Encoding::UndefinedConversionError) 20
「髙」 Unicode 上は別の文字なので同一文字として扱わなけれ ばいいんだけど、人名検索とかだと同一文字として扱いた いこともあるかもしれないのでむずかしい 21
「﨑」 CJK互換漢字 「令」と同じ だけど unicode_normalize では「崎」にならない > '﨑'.unicode_normalize "﨑" #
CJK互換漢字は普通は正規化できる > '福'.unicode_normalize "福" 22
「﨑」 これも「髙」と同じく変換するには個別対応が必要そう U+FA11(﨑)はU+5D0E(崎)に統 合漢字ブロックの異体字を持つが、字体 差が大きいとみなされ統合の範疇とされ ていない。 CJK互換漢字 - Wikipedia 23
これは同じ文字? へ ヘ 24
別の文字だけど日本語のバグ へ 平仮名 ヘ 片仮名 25
この文字数は? 26
国旗は2文字 U+1F1EF U+1F1F5 + 国コードを国旗用文字2文字で書くと国旗になる + = 27
3人家族は1文字 U+1F46A 「FAMILY」という絵文字 28
4人家族は7文字 U+1F468 MAN U+200D ゼロ幅接合子 U+1F469 WOMAN U+200D ゼロ幅接合子 U+1F467
GIRL U+200D ゼロ幅接合子 U+1F466 BOY 29
濁点つき文字 ぱ U+3071 ぱ U+306F U+309A 「は」+合成用半濁点文字 (これは unicode_normalize(:nfc) で1文字の「ぱ」になる)
30
囲み文字 a⃝ U+0041 U+20DD a⃤ U+0041 U+20E4 a⃞ U+0041 U+20DE
a ⃣ U+0041 U+20E3 31
人間の肌色と髪型 U+1F9D1(大人) + U+1F3FB(明るい肌色) + U+1F3FC(やや明るい肌色) U+200D U+1F9B0(赤毛) + U+1F3FE(やや濃い肌色)
U+200D U+1F9B2(坊主頭) 32
文字数とは? 33
プログラム的に自然なのは コードポイントの数 でも人にはわかりにくい > ' '.size 10 34
書記素 より 「人が1文字として見える文字」みたいな 書記素(しょきそ、英: grapheme)と は、書記言語において意味上の区別を 可能にする最小の図形単位をいう 書記素 - Wikipedia
35
Ruby で書記素を扱う String#grapheme_clusters > ' '.size 10 > ' '.grapheme_clusters
[" ", " ", " "] > ' '.grapheme_clusters.size 3 36
Ruby で書記素を扱う 正規表現 \X > ' '.scan(/./) [" ", "
", " ", " ", "", " ", "", " ", "", " "] > ' '.scan(/\X/) [" ", " ", " "] 37
まとめ • ユニコードはカオス • 文字列を比較するときは正規化 • 文字数はコードポイントなのか書記素なのかを考える 38