VIDEO LESSON
JavaScriptのnormalize():Unicode正規化で文字列の比較をそろえるの解説動画
再生時間 8:01動画を別のタブで開く ↗
動画の字幕・文字起こしを読む
再生中の字幕を濃い黒で表示し、一番上に追従します。字幕の行を選ぶと、その位置から再生できます。
- 0:00こんにちは。
- 0:00今回はジャバスクリプトのノーマライズを紹介します。
- 0:04文字列のユニコード正規化を行うメソッドです。
- 0:08検索対象にガという文字があるのに、入力したガと一致しない。
- 0:12そんな経験はありませんか。
- 0:14見た目はまったく同じなのに、コンピューターの内部では違う並びとして扱われていることが原因です。
- 0:22ノーマライズは、ユニコードで等しいと決められた表現を、共通の形にそろえてくれます。
- 0:28この動画では、四つの正規化形式の違いから、検索への応用、やってはいけない使い方までを、
- 0:32実行結果と一緒に学びます。
- 0:37比較で困ったときの対処法を、一つ増やしましょう。
- 0:40入力方法やコピー元の違いで表現がばらつくことは、実務でもよく起こります。
- 0:46まず、なぜ見た目が同じなのに一致しないのかを見ます。
- 0:50ジャバスクリプトの文字列比較は、画面の形を見て判断しません。
- 0:54内部のコードの並びが一文字でも違えば、厳密等価演算子の結果はフォルスになります。
- 1:00例えばガには、一文字で表す方法と、カに結合用の濁点を続ける二文字で表す方法があります。
- 1:07どちらも画面では同じガに見えますが、長さは一と二で異なります。
- 1:11そのため、そのまま比べると別物と判定されてしまいます。
- 1:15ノーマライズは、このような等価な表現の違いを吸収するための仕組みです。
- 1:21ただし、ひらがなとカタカナのような、もともと別の文字を同じにする機能ではありません。
- 1:27呼び出し方は、文字列に対してドット・ノーマライズと書き、引数に正規化形式の名前を渡します。
- 1:36戻り値は正規化後の新しい文字列で、元の文字列は変更されません。
- 1:42形式は四つあります。
- 1:43エヌエフシーは、分解してから可能なものを再び合成する形式です。
- 1:49エヌエフディーは、合成された文字を部品に分解する形式です。
- 1:55エヌエフシーケーシーとエヌエフシーケーディーは、互換等価という、より広い同一視を行います。
- 2:04全角英数字を半角にそろえるような変換が、こちらに含まれます。
- 2:09引数を省略した場合と、アンディファインドを渡した場合は、エヌエフシーが使われます。
- 2:17四つの形式を最初から使い分ける必要はありません。
- 2:20実務でのおすすめは、まずエヌエフシーから始めることです。
- 2:24同じ文字の表現違いだけをそろえたいなら、エヌエフシーで十分なことがほとんどです。
- 2:30一方、全角と半角のような文字幅の違いや、丸数字のような互換文字の違いまで検索で吸収したい場合は、
- 2:34エヌエフシーケーシーを検討します。
- 2:39分解した形で処理したい特別な理由がある場合にだけ、エヌエフディーやエヌエフシーケーディーを選びます。
- 2:46どの違いを同じと見なすかは、要件によって変わります。
- 2:49変換範囲が広いほど便利な反面、意味のある違いを消してしまう危険も高まる、
- 2:52と覚えてください。
- 2:56迷ったときは、変換前と変換後の例を並べて、消えてよい違いかどうかを確認すると安全です。
- 3:02基本のコードで、比較がどう変わるかを確認します。
- 3:05画面のコードでは、コピーしたときに違いが消えないよう、ガをユニコードエスケープで書いています。
- 3:11コンポーズドが一文字のガ、デコンポーズドがカと濁点の二文字です。
- 3:16正規化する前はイコールにならず、長さも一と二で異なります。
- 3:20両方にエヌエフシーを適用すると、同じ一文字にそろい、比較結果はトゥルーに変わります。
- 3:26このコードは、ノード・ジェイエスの実機でも、記事の期待出力と完全に一致することを確認済みです。
- 3:32ブラウザーのコンソールでも同じ結果になります。
- 3:35結果を読むときの注意を三つ押さえます。
- 3:39一つ目、ここで出てくる長さは、ユーティーエフ十六のコード単位数です。
- 3:45人が数える見た目の文字数とは、必ずしも一致しません。
- 3:50二つ目、正規化しても元の文字列自体は変わりません。
- 3:54変換したければ、戻り値を変数に受け取るか、そのまま比較に渡してください。
- 4:01三つ目、形式名は大文字で正確に書く必要があります。
- 4:05小文字でエヌエフシーと書くなど、指定できない形式を渡すと、レンジエラーが発生します。
- 4:13エラーの名前を確認する処理も、画面の考え方で試せます。
- 4:18実行前に形式名を見直す習慣を付けましょう。
- 4:22対応環境を確認します。
- 4:23ノーマライズは、二千十六年九月から主要ブラウザーを横断して利用できる機能で、
- 4:29現在のクローム、エッジ、ファイアフォックス、サファリで使えます。
- 4:34ノード・ジェイエスでも利用でき、記事の実行対象は二十四系です。
- 4:38ただし注意点があります。
- 4:40ノード・ジェイエスをアイシーユーなしで独自にビルドした環境では、メソッドが存在しても変換が行われないことがあります。
- 4:48そのため画面のように、関数があるかだけでなく、代表的な文字列が実際に正規化されるかまで確認すると確実です。
- 4:56対応が怪しい環境では、この確認を最初に行ってください。
- 5:00活用例として、商品検索を考えます。
- 5:03表示用の文字列はそのまま残し、比較専用の検索キーを別に用意する設計です。
- 5:09登録データの商品名から、エヌエフシーケーシーで正規化した検索キーをあらかじめ作っておきます。
- 5:17検索するときは、入力された文字も同じ形式で正規化してから、検索キーに含まれるかを調べます。
- 5:24こうすると、全角で入力されたエービーシーでも、半角で登録された商品を見つけられます。
- 5:31商品データの読み込み時にキーを作っておけば、検索のたびに行う変換は、検索語の分だけで済みます。
- 5:39商品名を更新したときは、キーも一緒に更新してください。
- 5:44実行結果を読みます。
- 5:46全角のエービーシーペンと、半角のエービーシーノートの二件が一致し、エックスワイゼットのケースは一致しませんでした。
- 5:55表示には元のラベルを使っているため、登録時の文字幅がそのまま保たれます。
- 6:01要点は、登録データと検索語の両方に、同じ形式を適用することです。
- 6:06片方だけを変換すると、もう片方に残った表現の違いで、一致しなくなってしまいます。
- 6:13なお、この例では空文字で検索すると全件が一致します。
- 6:17実際の画面で、空の入力をどう扱うかは、別途決めておいてください。
- 6:23この結果も実機で確認済みです。
- 6:25検索キーは使い捨ての索引と考えると、この設計の意図が分かりやすくなります。
- 6:31失敗例を確認します。
- 6:33エヌエフシーケーシーは強力ですが、元データの上書きには使わないでください。
- 6:39全角英数字だけでなく、丸数字なども変換されるため、表示や識別に意味のある違いが失われる可能性があります。
- 6:48別々の商品コードが、正規化のあとで同じ値になれば、キーの衝突が起きてしまいます。
- 6:54検索で候補を増やす用途と、データを一意に識別する用途は、要件を分けて考えてください。
- 7:01また、ノーマライズだけでは検索の要件を満たせないこともあります。
- 7:06大文字と小文字の区別、前後の空白の除去、ひらがなとカタカナの統一は、別の処理が必要です。
- 7:14まとめです。
- 7:14ノーマライズは、見た目が同じ文字列の、内部表現の違いをそろえるメソッドです。
- 7:20まずはエヌエフシーで同じ文字の表現をそろえ、文字幅などの違いも吸収したいときにエヌエフシーケーシーを検討してください。
- 7:30導入時の三つの約束を覚えておきましょう。
- 7:33比較する双方に同じ形式を適用すること。
- 7:36変換結果を必ず使うこと。
- 7:38そして、表示用の原文は保持することです。
- 7:41練習として、ガの二つの表現を用意し、正規化の前後で比較結果と長さがどう変わるかを予想してから、
- 7:46実行してみてください。
- 7:50小さな例で確かめる習慣が、検索の不具合を減らします。
- 7:54この考え方は、ユーザー入力を受け取るあらゆる画面で役立ちます。
- 7:59お疲れさまでした。
この動画で学べること
String.prototype.normalize()で、見た目が同じ文字列の比較失敗を解消する方法を解説。正規化形式の選び方、ブラウザーとNode.jsの実行手順、検索への応用と制約を学びます。
解説記事・サンプルコードを読む:JavaScriptのnormalize():Unicode正規化で文字列の比較をそろえる →