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

文字とはなにか - PHPの文字コード処理について -

てきめん tekimen
January 12, 2024
660

文字とはなにか - PHPの文字コード処理について -

PHPカンファレンス北海道2024

てきめん tekimen

January 12, 2024
Tweet

More Decks by てきめん tekimen

Transcript

  1. Unicodeって何? • 世界中のすべての文字を収録しようというもの – ISO/IEC 10646 という工業規格があって、Unicodeと等 しくなるようになっています • JIS

    X 0221が現在の日本の工業規格(JIS)での規格です – Unicodeのバージョンに伴って、収録されていく文字が 増えています
  2. UnicodeとJIS X 0221との関係 Unicode ISO/IEC 10646 JIS X 0221 同期

    日本版 ※各仕様書を読んだらこの図になりましたが「プログラマのための文字コード技術入 門」もほぼ同じ図になっていました
  3. 異体字セレクタについて • 漢字でも使われています – Ideographic Variation Sequence(漢字(表意文字)異体 字シーケンス、IVS)と呼ばれています – 範囲はU+E0100からU+E01EFです

    – 組み合わせを定義するのがIVS、字形を定義するデータ ベースをIVD(Ideographic Variation Database)といいま す – https://www.unicode.org/reports/tr37/
  4. 漢字の異体字セレクタについて • 例えば「邉」 CJK UNIFIED IDEOGRAPH-9089 – https://glyphwiki.org/wiki/u908a-ue0104 – https://747.github.io/vsselector/#!/ja/9089

    – 邉 邉󠄀 邉󠄁 邉󠄂 邉󠄃 邉󠄄 邉󠄅 邉󠄆 邉󠄈 邉󠄉 邉󠄊 邉󠄋 邉󠄌 邉󠄍 邉󠄎 … • 游ゴシック体で表示させました • すべて違う異体字です • 同じ漢字に見えるのもあれば違うのもありますね
  5. ICUというライブラリを使います • Grapheme cluster(グラフィム、書記素クラスター)単位で測れば 良い – それを格納しているのがICU – 結局データベースから測らないといけないのです •

    PHPではintl拡張に入っています – --enable-intlとしてコンパイルしましょう – grapheme_strlenを使えば測れます • https://www.php.net/grapheme_strlen
  6. アイヌ語の を考えてみましょう ト゚ • ト゚ はアイヌ語のカタカナだそうです – トゥというみたいですね – Unicodeには単独のコードポイントは存在しません

    • アイヌ語の濁音・半濁音はすべてこの様になっています • したがって、「ト」と「゚」の組み合わせで表現します – U+30C8とU+309Aの組み合わせです – 本当は単独のコードポイントにしたかったそうですね (ユニコード戦記を参照ください)(JIS X 0213では1面5区94点)
  7. 本来の濁音と半濁音 • JIS X 0201ではガのように文字と濁音が別々(いわゆる半角カ ナ) • JIS X 0208ではガのように、独立した文字も収録された

    • Unicodeでは独立した文字も別にできたりする – ガが果たしてU+30ACなのか、U+30ABとU+3099の両方なのかが一見 するとわからない – それを統一するのが「正規化」と呼ばれる
  8. 正規化の方法 • 正規化方式D(NFD) – $ sapi/cli/php -r 'var_dump(Normalizer::normalize("ガ", Normalizer::NFD));' string(6)

    "ガ" # カと濁音が分割されている • 正規化方式C(NFC) – $ sapi/cli/php -r 'var_dump(Normalizer::normalize("ガ", Normalizer::NFC));' string(3) "ガ" • 正規化方式KD(NFKD) – $ sapi/cli/php -r 'var_dump(Normalizer::normalize("ガ", Normalizer::NFKD));' string(6) "ガ" # カと濁音が分割されている • 正規化方式KC(NFKC) – $ sapi/cli/php -r 'var_dump(Normalizer::normalize("ガ", Normalizer::NFKC));' string(3) "ガ" • PHPではintlの Normalizerクラスを使 います • 正規化方式も4種あるの でその時適切な正規化 方式を選択する必要が あります
  9. まとめ • Unicodeにはバージョンがあることがわかりました • バージョンによって絵文字が表示されないことがわかりました • ZWJ、異体字セレクタなどで必ずしも1コードポイントに収まらないことがわかりました • 濁音・半濁音は色々な方法の組み合わせがあることがわかりました •

    PHPのUnicodeの対応具合がわかりました – mbstringでは1コードポイントごと、intlとPCREでは書記素クラスターとして測れる • 正規化は複雑すぎる、触れないでおければ幸せ • Unicodeは知ることが多いことがわかり、わからないことがわかりました – たとえば、不正なバイトシーケンスとか喋ってないですね? – あなたが知っていることがあったら、教えてください!
  10. 参照 • http://www.unicode.org/L2/L2016/16181-gender-zwj-sequences.pdf • https://ja.wikipedia.org/wiki/%E3%82%BC%E3%83%AD%E5%B9%85%E6%8E%A5 %E5%90%88%E5%AD%90 • https://www.unicode.org/glossary/#variation_selector • https://www.unicode.org/glossary/#ideographic_variation_sequence

    • https://www.unicode.org/reports/tr37/ • https://ja.wikipedia.org/wiki/%E7%95%B0%E4%BD%93%E5%AD%97%E3%82%B B%E3%83%AC%E3%82%AF%E3%82%BF#%E7%A8%AE%E9%A1%9E • https://emojipedia.org/ja/emoji-15.0 • https://747.github.io/vsselector/#!/ja/9089 • https://glyphwiki.org/wiki/u908a-ue0104 • https://www.php.net/grapheme_strlen