WEBVTT

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

2
00:00:00.903 --> 00:00:07.070
今回はジャバスクリプトのインターナショナル・セグメンターのセグメントを紹介します。

3
00:00:07.070 --> 00:00:15.043
入力欄の文字数表示やタイトルの短縮で困るのが、利用者が感じる一文字と、プログラムが数える一文字のずれです。

4
00:00:15.043 --> 00:00:20.383
笑顔の絵文字は見た目では一つでも、内部では別の数え方をされますし、濁点やアクセントが付いた文字は、

5
00:00:20.383 --> 00:00:25.723
切り方を間違えると途中でちぎれてしまいます。

6
00:00:25.723 --> 00:00:30.988
セグメントは、文字のまとまりを壊さずに文字列を分けるための仕組みです。

7
00:00:30.988 --> 00:00:35.200
この動画では、見た目の文字数を正しく数える方法と、まとまりを保ったまま短くする方法を、

8
00:00:35.200 --> 00:00:39.412
実行結果と一緒に学びます。

9
00:00:39.412 --> 00:00:41.926
まず、数え方の違いを整理します。

10
00:00:41.926 --> 00:00:48.054
文字列のレングスは、ユーティーエフ十六のコード単位という細かい単位で数えます。

11
00:00:48.054 --> 00:00:54.338
笑顔の絵文字はこの単位では二つ分になるため、レングスは見た目より大きくなります。

12
00:00:54.338 --> 00:01:00.780
次に、文字列を点三つで広げて配列にする方法は、コードポイントという単位で数えます。

13
00:01:00.780 --> 00:01:09.265
絵文字は一つにまとまりますが、英字にアクセントを合成した文字は、英字とアクセントの二つに分かれてしまいます。

14
00:01:09.265 --> 00:01:12.250
そこで登場するのが書記素クラスタです。

15
00:01:12.250 --> 00:01:18.849
これは利用者が一文字と認識するまとまりの単位で、合成された文字も一つとして扱えます。

16
00:01:18.849 --> 00:01:23.720
どの単位で数えるかで結果が変わる点が、このテーマの出発点です。

17
00:01:23.720 --> 00:01:25.344
動作環境を確認します。

18
00:01:25.344 --> 00:01:33.465
インターナショナル・セグメンターは、二千二十四年四月に主要ブラウザーで使えるようになった比較的新しい機能です。

19
00:01:33.465 --> 00:01:40.700
クロームとエッジは八十七以降、ファイアフォックスは百二十五以降、サファリは十四点一以降が目安です。

20
00:01:40.700 --> 00:01:46.015
ノード・ジェイエスでも使え、記事の実行対象は二十二系または二十四系です。

21
00:01:46.015 --> 00:01:51.183
画面要素には依存しないので、ブラウザーとノードで同じコードが動きます。

22
00:01:51.183 --> 00:01:55.907
ただし古いブラウザーやアプリ内の画面では未対応のことがあります。

23
00:01:55.907 --> 00:02:00.484
実行前に、セグメンターが使えるかどうかを必ず確認してください。

24
00:02:00.484 --> 00:02:05.652
ノードでは国際化データの構成によっても結果が変わる点に注意が必要です。

25
00:02:05.652 --> 00:02:06.916
基本の書き方です。

26
00:02:06.916 --> 00:02:10.849
まずニューでインターナショナル・セグメンターを作ります。

27
00:02:10.849 --> 00:02:14.782
第一引数はロケールで、日本語ならジェイエーを指定します。

28
00:02:14.782 --> 00:02:21.102
第二引数のグラニュラリティーにグラフィームを指定すると、書記素単位で分ける設定になります。

29
00:02:21.102 --> 00:02:23.209
この設定が既定値でもあります。

30
00:02:23.209 --> 00:02:30.091
作った分節器のセグメントに対象の文字列を渡すと、セグメンツという反復できるオブジェクトが返ります。

31
00:02:30.091 --> 00:02:32.900
配列でも文字数でもない点がポイントです。

32
00:02:32.900 --> 00:02:39.783
繰り返しで取り出すと、各要素には、切り取られた文字列、その開始位置、元の文字列全体が入っています。

33
00:02:39.783 --> 00:02:46.384
開始位置は書記素の通し番号ではなく、ユーティーエフ十六単位で数えた位置なので注意してください。

34
00:02:46.384 --> 00:02:50.843
数えるときは、セグメンツを配列に変換するのが便利です。

35
00:02:50.843 --> 00:02:58.440
アレイ・フロムの第二引数に関数を渡すと、各要素からセグメントだけを取り出して配列にできます。

36
00:02:58.440 --> 00:03:02.404
その配列の長さが、そのまま書記素の数になります。

37
00:03:02.404 --> 00:03:07.028
空の文字列を分けると要素はゼロ個なので、答えはゼロです。

38
00:03:07.028 --> 00:03:12.809
元の文字列を直接書き換える処理ではないため、入力はそのまま保たれます。

39
00:03:12.809 --> 00:03:18.094
カウントと短縮で同じ分節器を使い回すと、数え方に一貫性が出ます。

40
00:03:18.094 --> 00:03:23.709
関数にまとめる場合は、入力が文字列かどうかを最初に確認し、違う型ならタイプエラーを投げる形にすると、

41
00:03:23.709 --> 00:03:29.324
呼び出し側の間違いに早く気付けます。

42
00:03:29.324 --> 00:03:31.946
記事の中心となる実行例を読みます。

43
00:03:31.946 --> 00:03:39.040
対象は、大文字のエー、アクセント付きのイー、笑顔の絵文字、大文字のビーをつないだ文字列です。

44
00:03:39.040 --> 00:03:43.667
ユーティーエフ十六の単位数は六、コードポイント数は五でした。

45
00:03:43.667 --> 00:03:45.981
ところが書記素の数は四つです。

46
00:03:45.981 --> 00:03:54.155
アクセント付きのイーは二つのコードポイントからできていますが、一つのまとまりとして数えられているからです。

47
00:03:54.155 --> 00:03:59.244
分節結果は、エー、アクセント付きのイー、絵文字、ビーの四つでした。

48
00:03:59.244 --> 00:04:02.329
各要素の開始位置はゼロ、一、三、五です。

49
00:04:02.329 --> 00:04:08.344
途中に二単位ぶんを使う文字があるため、位置が飛んでいる点にも注目してください。

50
00:04:08.344 --> 00:04:13.896
これらの出力はノード・ジェイエスの実機でも同じになることを確認済みです。

51
00:04:13.896 --> 00:04:17.440
次に、まとまりを保ったまま短くする関数です。

52
00:04:17.440 --> 00:04:24.044
まず文字列を書記素の配列に分け、要素数が上限以下なら元の文字列をそのまま返します。

53
00:04:24.044 --> 00:04:31.454
上限を超える場合だけ、先頭から上限の数だけ要素を取り出してつなぎ、最後に省略記号を付けます。

54
00:04:31.454 --> 00:04:37.253
例えば上限を二にすると、先頭の二書記素に省略記号が付いた結果になります。

55
00:04:37.253 --> 00:04:42.246
ここで注意したいのは、上限は省略記号を除いた数だという点です。

56
00:04:42.246 --> 00:04:49.656
省略記号も含めて全体の上限を決めたい設計では、その一文字ぶんをあらかじめ差し引いてください。

57
00:04:49.656 --> 00:04:57.388
また上限の値は、ゼロ以上の整数であることを確認し、違う場合はレンジエラーを投げる形にしています。

58
00:04:57.388 --> 00:04:58.643
失敗例を見ます。

59
00:04:58.643 --> 00:05:03.348
アクセント付きのイーを、点三つで広げる方法で先頭だけ取り出すと、残るのは英字のイーだけで、

60
00:05:03.348 --> 00:05:08.053
アクセントが落ちてしまいます。

61
00:05:08.053 --> 00:05:14.954
見た目がわずかに変わるだけなので、テストで英数字しか使っていないと見逃しやすい失敗です。

62
00:05:14.954 --> 00:05:23.267
一方、セグメンターで書記素単位に分けてから先頭を取り出すと、アクセントまで含めた一文字がそのまま残ります。

63
00:05:23.267 --> 00:05:30.952
家族の絵文字や国旗の絵文字のように、複数の絵文字が合体して一つに見える文字でも同じことが起きます。

64
00:05:30.952 --> 00:05:36.128
切り出しや数え直しを行う処理では、単位の選び方が結果を左右します。

65
00:05:36.128 --> 00:05:38.149
例外と未対応への対処です。

66
00:05:38.149 --> 00:05:44.678
グラニュラリティーに無効な値を指定すると、コンストラクターがレンジエラーを投げます。

67
00:05:44.678 --> 00:05:50.896
またセグメンターはニュー付きで作る必要があり、省略するとタイプエラーになります。

68
00:05:50.896 --> 00:05:56.958
ここで混同しやすいのが、自作関数が入力チェックのために投げるタイプエラーです。

69
00:05:56.958 --> 00:06:03.487
これはエーピーアイ自体の仕様ではなく、自分の関数のルールとして分けて考えてください。

70
00:06:03.487 --> 00:06:10.638
処理は同期的で、プロミスは返らないため、アウェイトは不要で、例外はトライキャッチで受けます。

71
00:06:10.638 --> 00:06:14.913
未対応の環境では、数え方の違う方法へ黙って切り替えるより、対応環境を案内するほうが、

72
00:06:14.913 --> 00:06:19.188
文字数のルールを守れます。

73
00:06:19.188 --> 00:06:20.896
活用場面を見ましょう。

74
00:06:20.896 --> 00:06:27.261
プロフィール名の文字数カウンターでは、利用者が感じる文字数と表示をそろえられます。

75
00:06:27.261 --> 00:06:35.488
通知文や一覧タイトルのプレビューを短くするときも、絵文字やアクセント付き文字を途中で壊さずに切り取れます。

76
00:06:35.488 --> 00:06:38.283
分節単位は書記素だけではありません。

77
00:06:38.283 --> 00:06:43.018
ワードを指定すると単語単位、センテンスを指定すると文単位に分けることもでき、

78
00:06:43.018 --> 00:06:47.753
日本語の文章でも単語のまとまりを取り出せます。

79
00:06:47.753 --> 00:06:50.702
用途に応じて単位を使い分けてください。

80
00:06:50.702 --> 00:06:56.602
大切なのは、数える処理と切り取る処理で、必ず同じ分節器と単位を使うことです。

81
00:06:56.602 --> 00:07:02.656
単位がずれると、上限ぴったりのはずの文字列がはみ出すといった不整合が起きます。

82
00:07:02.656 --> 00:07:03.941
制約とまとめです。

83
00:07:03.941 --> 00:07:10.079
書記素の数は、ユーティーエフ八のバイト数でも、画面に表示したときの横幅でもありません。

84
00:07:10.079 --> 00:07:15.931
保存容量の制限やレイアウトの幅を調べたいときは、それぞれ別の方法で測ってください。

85
00:07:15.931 --> 00:07:21.499
また分節しても文字列が正規化されるわけではなく、元の表現はそのまま保たれます。

86
00:07:21.499 --> 00:07:27.779
ユニコードや国際化データの更新で、新しい絵文字の扱いが環境ごとに変わる可能性もあります。

87
00:07:27.779 --> 00:07:34.488
ブラウザーのカウントは入力の補助として使い、保存時の最終判定はサーバー側で行う設計が安全です。

88
00:07:34.488 --> 00:07:39.627
文字を数える、切り取る場面に迷ったら、まずセグメンターで書記素に分ける。

89
00:07:39.627 --> 00:07:41.911
この流れをぜひ活用してください。

90
00:07:41.911 --> 00:07:43.196
お疲れさまでした。
