Unicodeとマルチバイト文字とAmbiguous文字について
ChatGPTで調べたことをまとめた
code:markdown
## ✅ Unicodeとは
- 文字の **一意な符号化方式(コードポイント)** を定めた国際標準。
- 例:あ は Unicode で U+3042、A は U+0041。
- 単なる文字コードの集合であり、**バイト数や表示幅は定めていない**。
---
## ✅ マルチバイト文字とは
- **1文字を表現するのに複数バイトを使用する文字**。
- UTF-8 などでは、ASCII(英数字)は1バイト、それ以外は2〜4バイトになる。
| 文字 | UTF-8でのバイト数 | 備考 |
|------|------------------|------|
| A | 1バイト | 英数字、ASCII |
| あ | 3バイト | 日本語ひらがな |
| 漢 | 3バイト | 漢字 |
---
## ✅ AmbiguousなUnicode文字とは?
- **East Asian Ambiguous(曖昧な東アジア文字)** に分類されるUnicode文字群。
- 「**全角**とも**半角**とも言える」文字で、**環境によって表示幅(1 or 2)が変わる**。
- 例:→(矢印)、Ω(オメガ)、§(セクション記号)など。
---
## ✅ 環境やロケールによって文字幅が変わるとは?
### ● ロケール(locale)とは
- OSやターミナルの **言語・地域設定**(例: ja_JP.UTF-8, en_US.UTF-8)。
- これにより ambiguous な文字が **全角(2)か半角(1)かの解釈が変わる**。
### ● 具体例
| 環境 | 設定 | → の表示幅 |
|------|------|----------------|
| macOS Terminal(英語設定) | en_US.UTF-8 | 1 |
| macOS Terminal(日本語設定) | ja_JP.UTF-8 | 2 |
| VSCode Terminal(日本語フォント使用) | ja_JP.UTF-8 | 2 |
### ● ロケール変更例(bash)
`bash
LC_CTYPE=en_US.UTF-8 bash # 英語ロケール(半角解釈されやすい)
LC_CTYPE=ja_JP.UTF-8 bash # 日本語ロケール(全角解釈されやすい)
`
✅ Rubyで幅を確認する
code:ruby
require 'unicode/display_width'
puts Unicode::DisplayWidth.of("→", east_asian: false) # => 1
puts Unicode::DisplayWidth.of("→", east_asian: true) # => 2
✅ 注意点
ターミナルの文字ズレや整列ミスは、この ambiguous 文字幅の違いによって発生することがある。
表形式、ログ表示、罫線アートなどでズレが起きる原因となる。
曖昧な幅を避けるには:
明示的に全角/半角の文字を使う
フォントやターミナルの設定を固定する
Rubyなどで east_asian: true を使って処理する
✅ 参考資料