Upgrade to Pro — share decks privately, control downloads, hide ads and more …

文字を数えるのも楽じゃない

Avatar for QUANON QUANON
September 29, 2020

 文字を数えるのも楽じゃない

Avatar for QUANON

QUANON

September 29, 2020

More Decks by QUANON

Other Decks in Programming

Transcript

  1. 自己紹介 • Shinpei Noda (@quanon_jp) • Money Forward, Inc. •

    サーバサイドエンジニア • Ruby/Rails • 読書が大好き • 村上春樹主義者 • スリランカカレーが好き
  2. Unicode と UTF-X • Unicode • 文字集合 • ひとつひとつの文字に 符号位置

    と呼ばれる整数値を付けて管理してい る • UTF-X (UTF-8, UTF-16, UTF-32) • 文字符号化方式 • 符号位置の整数値をコンピュータが使用できるようにバイト列に変換す る
  3. UTF-16 コード単位でかぞえる • BMP (基本多言語面) 以外の面の文字を表すために サロゲートペア という仕組みがある。 • JavaScript

    の内部表現は UTF-16。 • String.length ではサロゲートペアは 2 とカウントされる。 Buffer.from('', 'utf16le').swap16(); //=> <Buffer d8 3e dd 37> '\uD83E\uDD37'; //=> '' '\uD83E\uDD37'.length; //=> 2 ''.length //=> 2 上位 サロゲート 下位 サロゲート
  4. ZWJ (ZERO WIDTH JOINER) • ゼロ幅接合子 • U+200D • 絵文字を結合するための

    接着剤の役割をする制御文字 • + + + = U+1F468 U+200D U+200D U+200D U+1F469 U+1F467 U+1F466
  5. 番外編: east asian width (東アジアの文字幅) 単位でかぞえる # Python from unicodedata

    import east_asian_width width_dict = { 'F': 2, # Fullwidth 'H': 1, # Halfwidth 'W': 2, # Wide 'Na': 1, # Narrow 'A': 2, # Ambiguous 'N': 1 # Neutral } string = 'Ꚋんは天使でアル ' chars = [char for char in string] #=> ['Ꚋ', 'ん', 'は', '天', '使', 'で', 'ア', 'ル', ' ', ''] east_asian_width_list = [east_asian_width(char) for char in chars] #=> ['N', 'W', 'W', 'W', 'W', 'W', 'H', 'H', 'Na', 'W'] width_list = [width_dict[east_asian_width] for east_asian_width in east_asian_width_list] #=> [1, 2, 2, 2, 2, 2, 1, 1, 1, 2] sum(width_list) #=> 16
  6. まとめ • 文字をかぞえるには • UTF-16 コード単位でかぞえる • Unicode コードポイント単位でかぞえる •

    書記素クラスタ単位でかぞえる ✨✨✨ • 文字幅をかぞえるには • east asian width 単位でかぞえる