Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
文字とはなにか - PHPの文字コード処理について - PHP Lovers Meetup #5
Search
てきめん tekimen
PRO
March 23, 2024
430
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
文字とはなにか - PHPの文字コード処理について - PHP Lovers Meetup #5
Gina Peter Banyardさんをお迎えして急遽行われたMeetupで発表したスライドです。PHPカンファレンス北海道2024のをちょっと修正を加えたものです。
てきめん tekimen
PRO
March 23, 2024
More Decks by てきめん tekimen
See All by てきめん tekimen
フロントエンドとバックエンドで「1文字」を揃えよう
youkidearitai
PRO
0
940
ChatGPTを使ってRaspberry Pi Picoの処理系を書いた
youkidearitai
PRO
0
110
PHP Internals わいわい #3 PIEを使ってみよう
youkidearitai
PRO
0
84
grapheme_strrev関数が採択されました(あと雑感)
youkidearitai
PRO
1
410
Limit of code point for grapheme cluster in programming language side.
youkidearitai
PRO
0
110
Unicodeどうしてる? PHPから見たUnicode対応と他言語での対応についてのお伺い
youkidearitai
PRO
2
3.8k
PHP 8.5の裏話
youkidearitai
PRO
0
170
CJK and Unicode From a PHP Committer
youkidearitai
PRO
0
490
PHP Internals わいわい #3 mb_*関数を作ってみよう
youkidearitai
PRO
0
180
Featured
See All Featured
SEO in 2025: How to Prepare for the Future of Search
ipullrank
3
3.8k
Money Talks: Using Revenue to Get Sh*t Done
nikkihalliwell
0
490
Designing Experiences People Love
moore
143
24k
Un-Boring Meetings
codingconduct
0
410
Navigating the moral maze — ethical principles for Al-driven product design
skipperchong
2
520
Tell your own story through comics
letsgokoyo
1
1.1k
Leo the Paperboy
mayatellez
9
2.3k
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
35
2.8k
SEOcharity - Dark patterns in SEO and UX: How to avoid them and build a more ethical web
sarafernandez
0
270
More Than Pixels: Becoming A User Experience Designer
marktimemedia
3
520
Bridging the Design Gap: How Collaborative Modelling removes blockers to flow between stakeholders and teams @FastFlow conf
baasie
0
690
The Power of CSS Pseudo Elements
geoffreycrofte
82
6.6k
Transcript
文字とはなにか - PHPの文字コード処理について - Ginaさんようこそバージョン
自己紹介 てきめん (tekimen) Yuya Hamada(濱田 侑弥) • https://tekitoh-memdhoi.info • X(twitter):
@youkidearitai • https://github.com/youkidearitai • https://mstdn.jp/tekimen • https://phpc.social/youkidearitai • サイボウズ株式会社に所属してます オレ
まずはじめに mb_ucfirst関数とmb_lcfirst関数がマージされました!
コンピューターで文字を表すの基本 • コンピューターは数値しか扱えません • そこで、とある数値をAなどと紐づけていきました • それが文字コードです • 文字コードに照らし合わせて文字を表示してくれる のがフォントですね
Unicodeがよい • ざっくり言ってしまうとUnicodeはいいぞ • 文字化けから開放してくれたぞ!ってなる • 絵文字も使えるぞ 🎉🎉
Unicodeって何? • 世界中のすべての文字を収録しようというもの – ISO/IEC 10646 という工業規格があって、Unicodeと等 しくなるようになっています • JIS
X 0221が現在の日本の工業規格(JIS)での規格です – Unicodeのバージョンに伴って、収録されていく文字が 増えています
UnicodeとJIS X 0221との関係 Unicode ISO/IEC 10646 JIS X 0221 同期
日本版 ※各仕様書を読んだらこの図になりましたが「プログラマのための文字コード技術入 門」もほぼ同じ図になっていました
Unicodeのバージョンについて • 現在最新版は15.1です。 • 2024年ではUnicode 16.0に むけて作業が進められていま す – http://blog.unicode.org/
2023/11/utc-177-highlig hts.html – alphaがリリースされました
絵文字の存在 • バージョンなんてどうでも良くね?と思いがちです が、実はそうもいかないのです • みなさんはこんなことはありませんか? – 私の推しマークは です、時々違う方がいます。気をつ 🩵
けてくださいなどと呼びかけているアイドルさん – 🙇 と♂♀が分割してた
スマートフォンは絵文字を入力しやすい • スマートフォンならば簡単に絵文字を選んで入力す ることができます • 新しいスマートフォンほど新しい絵文字を入力しやす くなります • その一方で、大切に長くスマートフォンを使っている 人もいます
その結果起こること • Unicodeのバージョンに気を使う必要があります – 古いスマートフォンでは絵文字が見えなかったり、分か れて見えたりします – 新しいスマートフォンでは当たり前のように新しい Unicodeのバージョンの絵文字が使えます
🩵はどうでしょうか • https://emojipedia.org/ja/%E6%B0%B4%E8% 89%B2%E3%81%AE%E3%83%8F%E3%83%BC %E3%83%88 • どうやらUnicode 15.0で入ったようです – 2023年現在の最新バージョンは15.1です
– かなり新しい絵文字です – 古いスマートフォンでは見えないでしょうね…
🙇と♂♀が分割してた • このケースの場合、土下座をしている人と♂や♀の マークが分割して見えることがあります • 対応している機種であれば、「 」、「 」と表示され 🙇♂️ 🙇♀️
ます • いきなりですがPHPでmb_strlenしてみましょう
mb_strlenした結果 • 1文字のハズなのに、4とでましたね – つまり、4つのコードポイントがあるということになります – mb_str_splitもしてみましょう
mb_str_splitした結果 このように、4つのコードポイントに分かれていること がわかりますし、 と♂が別れています 🙇
コードポイントとは • UnicodeでいうコードポイントとはU+1234などと 記す符号位置で、16進数で表します • mbstringではこの単位で測っていきます
コードポイントは? 2コードポイント目がU+200D、4コードポイント目 がU+FE0Fです
それぞれの意味 • U+200Dはゼロ幅接合子などと呼ばれてお り、Zero Width Joinerの略でZWJと言います • U+FE0Fは異体字セレクタと言い、U+FE00から U+FE0Fまでの範囲16文字を使って絵文字のバリ エーションを表現します
• https://www.unicode.org/glossary/#variation _selector
異体字セレクタについて • 漢字でも使われています – Ideographic Variation Sequence(漢字(表意文字)異体 字シーケンス、IVS)と呼ばれています – 範囲はU+E0100からU+E01EFです
– 組み合わせを定義するのがIVS、字形を定義するデータ ベースをIVD(Ideographic Variation Database)といいま す – https://www.unicode.org/reports/tr37/
漢字の異体字セレクタについて • 例えば「邉」 CJK UNIFIED IDEOGRAPH-9089 – https://glyphwiki.org/wiki/u908a-ue0104 – https://747.codeberg.page/vsselector/#!/ja/9089
– 邉 邉󠄀 邉󠄁 邉󠄂 邉󠄃 邉󠄄 邉󠄅 邉󠄆 邉󠄈 邉󠄉 邉󠄊 邉󠄋 邉󠄌 邉󠄍 邉󠄎 … • 游ゴシック体で表示させました • すべて違う異体字です • 同じ漢字に見えるのもあれば違うのもありますね
絵文字に戻っておさらいしましょう
mb_str_splitした結果 見えないほうはそのようにちがうわけですね ゼロ幅接合子 (ZWJ) U+200D (絵文字の)異体字セレクタ U+FE0F
どうすれば1文字として測れますか?
ICUというライブラリを使います • Grapheme cluster(グラフィム、書記素クラスター)単位で測れば 良い – それを格納しているのがICU – 結局データベースから測らないといけないのです •
PHPではintl拡張に入っています – --enable-intlとしてコンパイルしましょう – grapheme_strlenを使えば測れます • https://www.php.net/grapheme_strlen
PCRE(preg系関数)も使えます • PCREも書記素クラス ター単位での検出がで きます • \Xを使用します • https://www.pcre.or g/original/doc/html/
pcrepattern.html
grapheme_strlenした結果 このようにして、書記素クラスターを正しく数えるこ とができるわけですね
濁音・半濁音の場合
本来の濁音と半濁音 • JIS X 0201ではガのように文字と濁音が別々(いわゆる半角カ ナ) • JIS X 0208ではガのように、独立した文字も収録された
• Unicodeでは独立した文字も別にできたりする – ガが果たしてU+30ACなのか、U+30ABとU+3099の両方なのかが一見 するとわからない – それを統一するのが「正規化」と呼ばれる
正規化の方法 • 正規化方式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種あるの でその時適切な正規化 方式を選択する必要が あります
正規化で戸惑う例 • 例えばハングルの「アニョハセ ヨ」(こんにちは)を正規化 D(NFD)をすると、ハングルの 音節がバラバラに分解されて しまいます(ちゃんと表示できる 場合もありますが) • 参考:
https://www.unicode.org/c harts/normalization/ \
まとめ • Unicodeにはバージョンがあることがわかりました • バージョンによって絵文字が表示されないことがわかりました • ZWJ、異体字セレクタなどで必ずしも1コードポイントに収まらないことがわかりました • 濁音・半濁音は色々な方法の組み合わせがあることがわかりました •
PHPのUnicodeの対応具合がわかりました – mbstringでは1コードポイントごと、intlとPCREでは書記素クラスターとして測れる • 正規化は複雑すぎる、触れないでおければ幸せ • Unicodeは知ることが多いことがわかり、わからないことがわかりました – たとえば、不正なバイトシーケンスとか喋ってないですね? – あなたが知っていることがあったら、教えてください!
提案 • PHPのGrapheme関数には、文字列の処理関数が少ないように見 えます • 少なくとも、mb_str_split相当の書記素クラスターごとにarrayで返 却できるとarray関数で処理できてよいのではと思いますがどうで しょう? • つまり、grapheme_str_splitが必要なのではないかということです
– 絵文字などを「一文字」として配列として分割するというものです – RFCを作りました https://wiki.php.net/rfc/grapheme_str_split
参照 • 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.codeberg.page/vsselector/#!/ja/9089 • https://glyphwiki.org/wiki/u908a-ue0104 • https://www.php.net/grapheme_strlen