WEBVTT

1
00:00:00.000 --> 00:00:00.933
こんにちは。

2
00:00:00.933 --> 00:00:04.820
今回はジャバスクリプトのノーマライズを紹介します。

3
00:00:04.820 --> 00:00:08.241
文字列のユニコード正規化を行うメソッドです。

4
00:00:08.241 --> 00:00:12.750
検索対象にガという文字があるのに、入力したガと一致しない。

5
00:00:12.750 --> 00:00:14.772
そんな経験はありませんか。

6
00:00:14.772 --> 00:00:22.080
見た目はまったく同じなのに、コンピューターの内部では違う並びとして扱われていることが原因です。

7
00:00:22.080 --> 00:00:28.455
ノーマライズは、ユニコードで等しいと決められた表現を、共通の形にそろえてくれます。

8
00:00:28.455 --> 00:00:32.809
この動画では、四つの正規化形式の違いから、検索への応用、やってはいけない使い方までを、

9
00:00:32.809 --> 00:00:37.163
実行結果と一緒に学びます。

10
00:00:37.163 --> 00:00:40.894
比較で困ったときの対処法を、一つ増やしましょう。

11
00:00:40.894 --> 00:00:46.492
入力方法やコピー元の違いで表現がばらつくことは、実務でもよく起こります。

12
00:00:46.492 --> 00:00:50.380
まず、なぜ見た目が同じなのに一致しないのかを見ます。

13
00:00:50.380 --> 00:00:54.866
ジャバスクリプトの文字列比較は、画面の形を見て判断しません。

14
00:00:54.866 --> 00:01:00.847
内部のコードの並びが一文字でも違えば、厳密等価演算子の結果はフォルスになります。

15
00:01:00.847 --> 00:01:07.277
例えばガには、一文字で表す方法と、カに結合用の濁点を続ける二文字で表す方法があります。

16
00:01:07.277 --> 00:01:11.913
どちらも画面では同じガに見えますが、長さは一と二で異なります。

17
00:01:11.913 --> 00:01:15.950
そのため、そのまま比べると別物と判定されてしまいます。

18
00:01:15.950 --> 00:01:21.184
ノーマライズは、このような等価な表現の違いを吸収するための仕組みです。

19
00:01:21.184 --> 00:01:27.464
ただし、ひらがなとカタカナのような、もともと別の文字を同じにする機能ではありません。

20
00:01:27.464 --> 00:01:36.088
呼び出し方は、文字列に対してドット・ノーマライズと書き、引数に正規化形式の名前を渡します。

21
00:01:36.088 --> 00:01:42.029
戻り値は正規化後の新しい文字列で、元の文字列は変更されません。

22
00:01:42.029 --> 00:01:43.946
形式は四つあります。

23
00:01:43.946 --> 00:01:49.887
エヌエフシーは、分解してから可能なものを再び合成する形式です。

24
00:01:49.887 --> 00:01:55.445
エヌエフディーは、合成された文字を部品に分解する形式です。

25
00:01:55.445 --> 00:02:04.069
エヌエフシーケーシーとエヌエフシーケーディーは、互換等価という、より広い同一視を行います。

26
00:02:04.069 --> 00:02:09.818
全角英数字を半角にそろえるような変換が、こちらに含まれます。

27
00:02:09.818 --> 00:02:17.676
引数を省略した場合と、アンディファインドを渡した場合は、エヌエフシーが使われます。

28
00:02:17.676 --> 00:02:20.991
四つの形式を最初から使い分ける必要はありません。

29
00:02:20.991 --> 00:02:24.858
実務でのおすすめは、まずエヌエフシーから始めることです。

30
00:02:24.858 --> 00:02:30.382
同じ文字の表現違いだけをそろえたいなら、エヌエフシーで十分なことがほとんどです。

31
00:02:30.382 --> 00:02:34.870
一方、全角と半角のような文字幅の違いや、丸数字のような互換文字の違いまで検索で吸収したい場合は、

32
00:02:34.870 --> 00:02:39.359
エヌエフシーケーシーを検討します。

33
00:02:39.359 --> 00:02:46.264
分解した形で処理したい特別な理由がある場合にだけ、エヌエフディーやエヌエフシーケーディーを選びます。

34
00:02:46.264 --> 00:02:49.855
どの違いを同じと見なすかは、要件によって変わります。

35
00:02:49.855 --> 00:02:52.962
変換範囲が広いほど便利な反面、意味のある違いを消してしまう危険も高まる、

36
00:02:52.962 --> 00:02:56.069
と覚えてください。

37
00:02:56.069 --> 00:03:02.008
迷ったときは、変換前と変換後の例を並べて、消えてよい違いかどうかを確認すると安全です。

38
00:03:02.008 --> 00:03:05.342
基本のコードで、比較がどう変わるかを確認します。

39
00:03:05.342 --> 00:03:11.870
画面のコードでは、コピーしたときに違いが消えないよう、ガをユニコードエスケープで書いています。

40
00:03:11.870 --> 00:03:16.315
コンポーズドが一文字のガ、デコンポーズドがカと濁点の二文字です。

41
00:03:16.315 --> 00:03:20.343
正規化する前はイコールにならず、長さも一と二で異なります。

42
00:03:20.343 --> 00:03:26.177
両方にエヌエフシーを適用すると、同じ一文字にそろい、比較結果はトゥルーに変わります。

43
00:03:26.177 --> 00:03:32.705
このコードは、ノード・ジェイエスの実機でも、記事の期待出力と完全に一致することを確認済みです。

44
00:03:32.705 --> 00:03:35.900
ブラウザーのコンソールでも同じ結果になります。

45
00:03:35.900 --> 00:03:39.362
結果を読むときの注意を三つ押さえます。

46
00:03:39.362 --> 00:03:45.558
一つ目、ここで出てくる長さは、ユーティーエフ十六のコード単位数です。

47
00:03:45.558 --> 00:03:50.296
人が数える見た目の文字数とは、必ずしも一致しません。

48
00:03:50.296 --> 00:03:54.852
二つ目、正規化しても元の文字列自体は変わりません。

49
00:03:54.852 --> 00:04:01.412
変換したければ、戻り値を変数に受け取るか、そのまま比較に渡してください。

50
00:04:01.412 --> 00:04:05.968
三つ目、形式名は大文字で正確に書く必要があります。

51
00:04:05.968 --> 00:04:13.621
小文字でエヌエフシーと書くなど、指定できない形式を渡すと、レンジエラーが発生します。

52
00:04:13.621 --> 00:04:18.541
エラーの名前を確認する処理も、画面の考え方で試せます。

53
00:04:18.541 --> 00:04:22.368
実行前に形式名を見直す習慣を付けましょう。

54
00:04:22.368 --> 00:04:23.962
対応環境を確認します。

55
00:04:23.962 --> 00:04:29.035
ノーマライズは、二千十六年九月から主要ブラウザーを横断して利用できる機能で、

56
00:04:29.035 --> 00:04:34.107
現在のクローム、エッジ、ファイアフォックス、サファリで使えます。

57
00:04:34.107 --> 00:04:38.600
ノード・ジェイエスでも利用でき、記事の実行対象は二十四系です。

58
00:04:38.600 --> 00:04:40.339
ただし注意点があります。

59
00:04:40.339 --> 00:04:48.745
ノード・ジェイエスをアイシーユーなしで独自にビルドした環境では、メソッドが存在しても変換が行われないことがあります。

60
00:04:48.745 --> 00:04:56.427
そのため画面のように、関数があるかだけでなく、代表的な文字列が実際に正規化されるかまで確認すると確実です。

61
00:04:56.427 --> 00:05:00.340
対応が怪しい環境では、この確認を最初に行ってください。

62
00:05:00.340 --> 00:05:03.218
活用例として、商品検索を考えます。

63
00:05:03.218 --> 00:05:09.313
表示用の文字列はそのまま残し、比較専用の検索キーを別に用意する設計です。

64
00:05:09.313 --> 00:05:17.101
登録データの商品名から、エヌエフシーケーシーで正規化した検索キーをあらかじめ作っておきます。

65
00:05:17.101 --> 00:05:24.720
検索するときは、入力された文字も同じ形式で正規化してから、検索キーに含まれるかを調べます。

66
00:05:24.720 --> 00:05:31.831
こうすると、全角で入力されたエービーシーでも、半角で登録された商品を見つけられます。

67
00:05:31.831 --> 00:05:39.789
商品データの読み込み時にキーを作っておけば、検索のたびに行う変換は、検索語の分だけで済みます。

68
00:05:39.789 --> 00:05:44.360
商品名を更新したときは、キーも一緒に更新してください。

69
00:05:44.360 --> 00:05:46.027
実行結果を読みます。

70
00:05:46.027 --> 00:05:55.527
全角のエービーシーペンと、半角のエービーシーノートの二件が一致し、エックスワイゼットのケースは一致しませんでした。

71
00:05:55.527 --> 00:06:01.527
表示には元のラベルを使っているため、登録時の文字幅がそのまま保たれます。

72
00:06:01.527 --> 00:06:06.860
要点は、登録データと検索語の両方に、同じ形式を適用することです。

73
00:06:06.860 --> 00:06:13.527
片方だけを変換すると、もう片方に残った表現の違いで、一致しなくなってしまいます。

74
00:06:13.527 --> 00:06:17.860
なお、この例では空文字で検索すると全件が一致します。

75
00:06:17.860 --> 00:06:23.193
実際の画面で、空の入力をどう扱うかは、別途決めておいてください。

76
00:06:23.193 --> 00:06:25.693
この結果も実機で確認済みです。

77
00:06:25.693 --> 00:06:31.860
検索キーは使い捨ての索引と考えると、この設計の意図が分かりやすくなります。

78
00:06:31.860 --> 00:06:33.501
失敗例を確認します。

79
00:06:33.501 --> 00:06:39.572
エヌエフシーケーシーは強力ですが、元データの上書きには使わないでください。

80
00:06:39.572 --> 00:06:48.105
全角英数字だけでなく、丸数字なども変換されるため、表示や識別に意味のある違いが失われる可能性があります。

81
00:06:48.105 --> 00:06:54.669
別々の商品コードが、正規化のあとで同じ値になれば、キーの衝突が起きてしまいます。

82
00:06:54.669 --> 00:07:01.561
検索で候補を増やす用途と、データを一意に識別する用途は、要件を分けて考えてください。

83
00:07:01.561 --> 00:07:06.812
また、ノーマライズだけでは検索の要件を満たせないこともあります。

84
00:07:06.812 --> 00:07:14.032
大文字と小文字の区別、前後の空白の除去、ひらがなとカタカナの統一は、別の処理が必要です。

85
00:07:14.032 --> 00:07:14.978
まとめです。

86
00:07:14.978 --> 00:07:20.967
ノーマライズは、見た目が同じ文字列の、内部表現の違いをそろえるメソッドです。

87
00:07:20.967 --> 00:07:30.267
まずはエヌエフシーで同じ文字の表現をそろえ、文字幅などの違いも吸収したいときにエヌエフシーケーシーを検討してください。

88
00:07:30.267 --> 00:07:33.420
導入時の三つの約束を覚えておきましょう。

89
00:07:33.420 --> 00:07:36.415
比較する双方に同じ形式を適用すること。

90
00:07:36.415 --> 00:07:38.306
変換結果を必ず使うこと。

91
00:07:38.306 --> 00:07:41.459
そして、表示用の原文は保持することです。

92
00:07:41.459 --> 00:07:46.030
練習として、ガの二つの表現を用意し、正規化の前後で比較結果と長さがどう変わるかを予想してから、

93
00:07:46.030 --> 00:07:50.601
実行してみてください。

94
00:07:50.601 --> 00:07:54.699
小さな例で確かめる習慣が、検索の不具合を減らします。

95
00:07:54.699 --> 00:07:59.585
この考え方は、ユーザー入力を受け取るあらゆる画面で役立ちます。

96
00:07:59.585 --> 00:08:01.004
お疲れさまでした。
