正規化前後のUnicode文字列を比較する
Unicodeコード表のテキスト解析でNFC・NFD・NFKC・NFKDを比較できます。Fancy Text Generator自体には汎用逆変換機能はありません。
結論:NFKCで戻せる互換文字だけを変換し、戻せない装飾は原文から復元する
𝐇𝐞𝐥𝐥𝐨のMathematical Alphanumeric SymbolsはNFKCでHelloへ変わります。全角英数字や一部の丸囲み文字もCompatibility Decompositionを持ちます。
Small Capsの近似字、Upside-down、取り消し線・下線のCombining Mark、独自に似た文字を割り当てた文字列はNFKCだけで元通りになるとは限りません。
現行Fancy Text Generatorは逆変換を実装していません。Unicodeコード表で正規化結果を確認し、元データを上書きしないでください。
戻せる文字と戻せない文字を判定する
文字列をNFKCへ正規化し、期待するASCIIへ変わった箇所と残った箇所をCode Point単位で確認します。
NFKCは意味のある表記差を失う場合があるため、識別子、署名、検索Indexへ無条件に適用しません。
| 確認項目 | 確認方法 | 判断 |
|---|---|---|
| Mathematical letters | NFKC結果 | ASCII化を確認 |
| Fullwidth/Circled | 互換分解 | 意図した値か確認 |
| Combining decoration | Mark残存を確認 | 個別除去を検討 |
| 近似文字 | Code Point対応表 | 自動復元しない |
普通の文字へ戻す安全な手順
- 元の特殊文字列を複製して保存します。
- Unicodeコード表へ貼り付けてCode Pointを確認します。
- NFKC結果を通常文字と比較します。
- 残った文字は発生元のMappingが分かる場合だけ個別に戻します。
- 検索・保存・表示の要件を満たすか確認します。
正規化後の結果を元データへ即時上書きせず、差分を確認します。
NFKCによる代表的な変化
'𝐇𝐞𝐥𝐥𝐨'.normalize('NFKC') // 'Hello'
'ABC'.normalize('NFKC') // 'ABC'
'①'.normalize('NFKC') // '1'
変換結果はBrowserのUnicode Normalization実装に基づきます。元の装飾情報は失われるため、Reverse可能な変換とは区別します。
CSSのフォント変更ではなくUnicode文字への置換
| 方法 | 文字列 | 内部で変わるもの |
|---|---|---|
| CSS Font | A → A | U+0041のままGlyphをFontで描き分ける |
| Fancy Unicode | A → 𝐀 | U+0041からU+1D400へCode Point自体を置換する |
| 結合装飾 | A → A̲ | U+0041の後ろへCombining Low Lineを追加する |
Mathematical Alphanumeric Symbolsは数式中の意味を区別するために定義された文字群です。SNS向けのおしゃれ文字は、それらを装飾目的で利用するケースが多く、CSSのfont-familyをコピーしているわけではありません。
NFC・NFD・NFKC・NFKDは目的を分けて使う
| 形式 | 主な処理 | 装飾文字への影響 |
|---|---|---|
| NFC | Canonical Decomposition後に可能な文字をComposition | 正準等価な表現をそろえるが、すべての装飾をASCIIへ戻すものではない |
| NFD | Canonical Decomposition | éをeとCombining Acute Accentへ分解する例がある |
| NFKC | Compatibility Decomposition後にComposition | 𝐀、𝔸、A、①等がAや1へ変わる場合がある |
| NFKD | Compatibility Decomposition | 互換文字を分解し、さらに結合列になる場合がある |
NFKCは一部のおしゃれ文字を普通の英数字へ近づける手段ですが、上下反転、Small Capsの近似文字、結合下線などを完全に元へ戻す汎用逆変換ではありません。元表記を保存する必要があるデータへ自動適用しません。
文字数はGrapheme・Code Point・UTF-16で分ける
| 数え方 | 𝐀の値 | 用途 |
|---|---|---|
| Grapheme Cluster | 1 | 利用者が見た目で認識する文字数 |
| Unicode Code Point | 1(U+1D400) | 文字の割り当て番号とUnicode処理 |
| JavaScript String.length | 2 UTF-16 Code Units | JavaScriptの添字・既存の入力制限 |
| UTF-8 | 4 Bytes | DB、API、File、通信時の保存容量 |
結合文字やZWJ Emojiは複数Code Pointでも1 Graphemeに見える場合があります。JavaScriptで見た目の文字数を数えるならIntl.Segmenter、Code Point単位ならfor...ofやArray.fromを使い、split("")だけに依存しません。
DevelopToolsで確認できる範囲と、できない範囲
| 項目 | 現行ツールの動作 |
|---|---|
| 入力 | 英字・数字を中心に変換し、日本語、絵文字、改行、未対応記号は削除せずそのまま残す |
| 21スタイル | Serif/Sansの太字・斜体、Monospace、Script、Fraktur、Double-Struck、Circled、Squared、Small Caps、上付き・下付き、上下反転、取り消し線・下線 |
| Unicode処理 | Intl.Segmenterが使える場合はGrapheme Cluster単位で処理し、使えない場合もArray.fromでSurrogate Pairを分割しない |
| 表示確認 | スタイルごとの変換文字数と対象文字数を表示し、未対応文字を見つけやすくする |
| 保存 | 各結果のコピー、TXT保存、お気に入り、最近コピーしたスタイルの並べ替えに対応 |
| 未対応 | 全角・括弧囲み、汎用的な逆変換、NFC/NFD/NFKC/NFKD実行、Unicode名・Code Point解析、Mixed Script/Confusable検出 |
| データ保持 | 入力文と変換結果はServerへ送信せず、LocalStorageへも保存しない。表示設定とお気に入りだけを端末内へ保存 |
文字を普通の英数字へ戻す、正規化結果を比較する、Code Pointを解析する場合はUnicodeコード表を併用します。文字数・UTF-8バイト・UTF-16コード単位を比べる場合は文字数カウントツールを使います。
表示互換性・検索性・アクセシビリティを確認する
- 利用先のFontにGlyphがなければ□や空白に見えるため、実際の端末とApplicationへ貼り付けて確認する
- プロフィール本文で表示できても、UsernameやIDの許可文字・文字数・正規化規則を満たすとは限らない
- 検索、読み上げ、音声入力、Copy後の再編集が必要な重要情報には通常文字を併記する
- Latin・Greek・Cyrillic等の見た目が似た文字を識別子へ混在させず、なりすましや誤認へ利用しない
- Password、URL、Email Address、Source Code、署名対象データへ装飾Unicodeを使わない
DevelopToolsで表示できることは、すべてのOS、SNS、Browser、Applicationで同じGlyphが表示される保証ではありません。Platformの仕様は変わるため、特定サービスで必ず使えるとは案内しません。
UnicodeとJavaScriptの一次資料
- Unicode UAX #15:Unicode Normalization Forms
- Unicode UAX #29:Unicode Text Segmentation
- Unicode UTS #39:Unicode Security Mechanisms
- Unicode:Mathematical Alphanumeric Symbols
- MDN:String.length
- MDN:String.prototype.normalize()
- MDN:Intl.Segmenter
NormalizationはUAX #15、Grapheme ClusterはUAX #29、ConfusableとIdentifier SecurityはUTS #39を基準にします。JavaScriptの実装はMDNのString.length、normalize()、Intl.Segmenterの説明と照合します。
具体例:𝐇𝐞𝐥𝐥𝐨をHelloへ戻す
Unicodeコード表へ貼り、原文とNFKC結果を並べます。
Mathematical lettersがASCII lettersへCompatibility Decompositionされ、Helloになります。
- 原文を保存
- Code Pointを表示
- NFKCを確認
- 差分を確認
- Copy先で再確認
元のStyleへ再変換できる情報はNFKC結果に残りません。
よくある質問
- 変換した文字はすべての端末で同じように表示されますか?
- 保証できません。Code Pointが正しくても、OSやApplicationのFontがGlyphを持たなければ□になり、Fontの違いで字形も変わります。利用先で実表示を確認してください。
- 入力した文章はServerへ送信または保存されますか?
- 現行の特殊文字・おしゃれ文字変換ツールはBrowser内で変換し、入力文と結果をServerやLocalStorageへ保存しません。端末内へ保存するのは表示設定とお気に入りだけです。
- NFKCを実行すれば必ず普通の文字へ戻せますか?
- 戻せるのは互換分解が定義された文字です。上下反転、近似文字、独自Mapping、結合装飾等はLosslessに戻せない場合があるため、元文字列を保持してください。