●JavaScriptで文字数カウントの基本
JavaScriptを使ってWebアプリケーションを開発していると、文字数をカウントする必要性に頻繁に遭遇します。
ユーザー入力のバリデーションや、SNSへの投稿文字数制限など、様々なシーンで正確な文字数カウントが求められます。
文字数をカウントする際の基本は、JavaScriptが提供するlengthプロパティを活用することです。
lengthプロパティは文字列の長さを取得するために使われ、シンプルかつ直感的に文字数を知ることができます。
○lengthプロパティで文字列の長さを取得
lengthプロパティは、文字列オブジェクトに含まれる便利なプロパティの1つです。
文字列変数の後ろに.lengthを付けるだけで、その文字列の長さを整数値で返してくれます。
○サンプルコード1:lengthプロパティの使用例
次のサンプルコードは、lengthプロパティを使って文字列の長さを取得する基本的な例です。
この例では、”こんにちは、JavaScript!”という文字列を変数messageに代入しています。
message.lengthとすることで、この文字列の長さが14であることが分かります。
○全角文字と半角文字の違いに注意
ただし、lengthプロパティを使う際には、全角文字と半角文字の扱いに注意が必要です。
JavaScriptでは、全角文字も半角文字も1文字としてカウントされます。
しかし、日本語の文章では、全角文字は見た目上のスペースを2つ分取るため、半角文字の2倍の幅を持っていると考えるのが一般的です。
そのため、単純にlengthプロパティを使うだけでは、全角文字と半角文字が混在する文字列の長さを正確に求めることができません。
日本語の文章を扱うWebアプリケーションでは、全角文字を2文字分としてカウントし、半角文字を1文字分としてカウントする処理が必要になります。
○サンプルコード2:全角半角を考慮したカウント
下記のサンプルコードは、全角文字を2文字分、半角文字を1文字分としてカウントする関数の例です。
この関数では、文字列を1文字ずつ確認し、charCodeAtメソッドでUnicodeコードポイントを取得しています。
Unicodeコードポイントが0から255の範囲内なら半角文字として1文字、それ以外は全角文字として2文字としてカウントします。
サンプルコードの実行結果は18になります。
“Hello, “は半角文字で7文字、”こんにちは!”は全角文字で5文字の2倍の10文字、合計で18文字としてカウントされるわけです。
●サロゲートペアに対応した文字数カウント
JavaScriptで文字数をカウントする際、もう1つ考慮すべき重要な点があります。
それは、サロゲートペアと呼ばれる特殊な文字の扱いです。
サロゲートペアに対応することで、絵文字などの特殊な文字を含む文字列の長さを正確に求めることができるようになります。
○サロゲートペアとは
サロゲートペアとは、Unicodeにおいて、2つのUTF-16コードユニットの組み合わせで表現される文字のことを指します。
一般的なUnicodeの文字は、1つのUTF-16コードユニットで表現されますが、一部の特殊な文字は、1つのコードユニットでは表現できません。
そのような文字をサロゲートペアで表現するのです。
絵文字や特殊な記号などは、サロゲートペアで表現されることが多いです。
例えば、😊のような絵文字は、サロゲートペアを使って表現されています。
○サンプルコード3:サロゲートペア対応のカウント関数
次のサンプルコードは、サロゲートペアを考慮した文字数カウント関数の例です。
この関数では、文字列を1文字ずつ確認し、サロゲートペアの判定を行っています。
Unicodeコードポイントが0xD800から0xDBFFの範囲内なら上位サロゲート、0xDC00から0xDFFFの範囲内なら下位サロゲートとして扱います。
上位サロゲートの次の文字が下位サロゲートである場合、2文字分としてカウントします。
サンプルコードの実行結果は21になります。
“こんにちは”は全角文字で5文字の2倍の10文字、絵文字の😊はサロゲートペアで2文字、”JavaScript!”は半角文字で11文字、合計で21文字としてカウントされるわけです。
○絵文字などでサロゲートペアを考慮する必要性
絵文字を使ったメッセージングアプリやSNSが普及した今、絵文字を含む文字列の長さを正確に求めることは非常に重要です。
絵文字1つが2文字分の長さを持つことを考慮しないと、文字数制限のある投稿で予期せぬ不具合が起きてしまうかもしれません。
また、絵文字以外にも、特殊な記号や古代文字などもサロゲートペアで表現されることがあります。
あらゆる文字を正しく扱えるようにするためには、サロゲートペアへの対応は欠かせません。
サロゲートペアを考慮することで、文字数カウントの精度が格段に上がります。
ユーザーが入力した文字列の長さを正確に判定できるようになり、アプリケーションの信頼性が向上するでしょう。
文字数を扱う際は、サロゲートペアの存在を忘れずに、適切に処理することが大切です。
●正規表現を使った文字数カウント
JavaScriptで文字数をカウントする方法として、正規表現を使ったアプローチがあります。
正規表現を使えば、特定の文字だけをカウントしたり、特定のパターンにマッチする文字列の出現回数を数えたりすることができます。
例えば、URLに含まれるハイフンの数を数えたいとか、英語の文章に含まれる特定の単語の出現回数を調べたいといった場合に、正規表現を使った文字数カウントが威力を発揮します。
○正規表現で特定の文字をカウント
正規表現を使って特定の文字をカウントするには、match()
メソッドを使います。
match()
メソッドは、正規表現にマッチした部分文字列を配列で返します。
その配列の長さを取得することで、マッチした文字数がわかるというわけです。
○サンプルコード4:正規表現でのカウント例
次のサンプルコードは、正規表現を使って文字列に含まれるハイフンの数をカウントする例です。
この関数では、/-/g
という正規表現を使っています。
-
はハイフンを表し、g
は全体マッチを意味します。
str.match(/-/g)
とすることで、文字列内のすべてのハイフンにマッチします。
マッチした結果は配列で返されるので、その配列の長さを返すことでハイフンの数がわかります。
ただし、マッチする文字がない場合はnull
が返されるので、その場合は0を返すようにしています。
○正規表現の基本的な使い方
正規表現は、文字列のパターンを表現するための特殊な記法です。
正規表現を使えば、特定の文字やパターンにマッチする部分文字列を検索したり、置換したりすることができます。
正規表現の基本的な記法は次の通りです。
.
-> 任意の1文字にマッチ*
-> 直前の文字の0回以上の繰り返しにマッチ+
-> 直前の文字の1回以上の繰り返しにマッチ?
-> 直前の文字の0回または1回の出現にマッチ^
-> 文字列の先頭にマッチ$
-> 文字列の末尾にマッチ\d
-> 数字にマッチ\w
-> 英数字とアンダースコアにマッチ\s
-> 空白文字にマッチ[...]
-> カッコ内の任意の1文字にマッチ[^...]
-> カッコ内の文字以外の任意の1文字にマッチ
これらの記法を組み合わせることで、複雑なパターンを表現できます。
例えば、/^[A-Z][a-z]*$/
という正規表現は、大文字で始まり、その後に0文字以上の小文字が続くような文字列にマッチします。
正規表現を使いこなせば、文字列処理の幅が大きく広がります。
文字数カウントにおいても、単純な文字数だけでなく、特定のパターンを満たす部分文字列の数を数えるといった応用が可能になるでしょう。
●文字列の切り出しと文字数制限
JavaScriptで文字数をカウントする際、文字列の一部を切り出して処理したいケースがあります。
例えば、SNSの投稿文字数制限に合わせて文字列を切り詰めたり、入力フォームで文字数オーバーのアラートを表示したりする場合などです。
文字列を切り出すことで、必要な部分だけを取り出し、文字数制限に合わせた処理を行うことができます。
JavaScriptには、文字列を切り出すための便利なメソッドが用意されています。
○substringとsliceで文字列を切り出す
JavaScriptには、文字列を切り出すための代表的なメソッドとして、substring()
とslice()
があります。
どちらも、指定した位置から文字列を切り出すことができます。
substring()
は、開始位置と終了位置を指定して文字列を切り出します。
終了位置は切り出す部分に含まれません。一方、slice()
は、開始位置と切り出す文字数を指定します。
マイナスの値を指定すると、文字列の末尾からの位置として扱われます。
ここでは、substring()
とslice()
の使用例を見てみましょう。
substring(0, 5)
とslice(0, 5)
は、どちらも0番目の文字から5番目の文字までを切り出します。
slice(-6)
は、文字列の末尾から6文字分を切り出します。
○サンプルコード5:文字数制限の実装例
次のサンプルコードは、文字列を指定された文字数で切り詰める関数の例です。
この関数では、文字列の長さが指定された最大文字数以下であれば、そのまま文字列を返します。
最大文字数を超える場合は、slice()
を使って先頭から最大文字数分だけ切り出し、末尾に"..."
を付け加えて返します。
このように、文字数制限を実装する際は、slice()
を使って文字列を切り出すことが一般的です。
切り出した文字列に省略記号を付け加えることで、文字数制限を超えた部分が省略されていることを表すこともできます。
○文字数オーバー時のアラート表示
文字数制限を設ける際、ユーザーが文字数をオーバーした場合にアラートを表示することで、入力の修正を促すことができます。
この例では、checkLength()
関数で文字列の長さが最大文字数を超えているかをチェックし、超えている場合はalert()
でアラートを表示しています。
また、addEventListener()
を使って、テキストエリアの入力イベントを監視し、入力があるたびにcheckLength()
を呼び出しています。
これで、リアルタイムで文字数のチェックが行われ、文字数オーバー時にすぐにアラートが表示されます。
文字数制限とアラート表示を組み合わせることで、ユーザーに適切な入力を促し、文字数オーバーによるエラーを未然に防ぐことができるでしょう。
●jQueryを使った文字数カウント
JavaScriptで文字数をカウントする際、jQueryを使うと便利な場面があります。
特に、フォームの入力文字数をリアルタイムで表示したい場合などは、jQueryを使うことで簡単に実装できます。
jQueryは、JavaScriptのライブラリの1つで、DOMの操作や非同期通信を手軽に行えるようにするものです。
jQueryを使えば、少ないコード量で動的なウェブページを作成することができます。
○jQueryでリアルタイムにカウントを表示
jQueryを使ってリアルタイムに文字数をカウントするには、input
イベントを監視し、入力のたびに文字数を数えて表示するようにします。
この例では、テキストエリアのinput
イベントを監視し、入力があるたびに文字数を計算しています。
maxLength
で最大文字数を設定し、現在の入力文字数をmaxLength
から引くことで、残り文字数を求めています。
残り文字数は、id
がremaining
の要素に表示されます。
jQueryのtext()
メソッドを使って、残り文字数を動的に更新しています。
○サンプルコード6:jQueryのカウント例
ここでは、jQueryを使ってSNSの投稿文字数制限を実装した例を紹介します。
この例では、maxlength
属性を使って最大文字数を設定しています。
残り文字数の表示は、先ほどの例と同様です。
さらに、残り文字数がマイナスになった場合は、残り文字数の表示を赤色にするようにしています。
jQueryのcss()
メソッドを使って、残り文字数の色を動的に変更しています。
○textareaやinputでの文字数カウント
jQueryを使った文字数カウントは、<textarea>
だけでなく、<input type="text">
でも同様に実装できます。
この例では、<input>
のmaxlength
属性で最大文字数を設定し、残り文字数を表示しています。
<textarea>
での例と同じように、input
イベントを監視し、入力のたびに残り文字数を更新しています。
jQueryを使った文字数カウントは、ユーザーにとって分かりやすく、インタラクティブな機能を提供できます。
残り文字数をリアルタイムで表示することで、ユーザーは自分の入力文字数を常に把握でき、文字数制限を超えないように調整できます。
また、jQueryを使えば、残り文字数の表示だけでなく、文字数オーバー時の装飾やアラート表示なども簡単に実装できます。
jQueryの豊富なメソッドを活用することで、文字数カウントに関連する様々な機能を実現できるでしょう。
文字数カウントは、ユーザーにとって重要な機能の1つです。
jQueryを使って文字数カウントを実装することで、ユーザビリティの高いフォームを作成することができます。
jQueryの使い方を覚えておくと、文字数カウントに限らず、様々な場面で役立つはずです。
●バイト数としての文字数カウント
JavaScriptで文字数をカウントする際、文字数だけでなく、バイト数を考慮する必要がある場面があります。
特に、データの保存やネットワーク通信では、バイト数が重要になってきます。
文字数とバイト数は、必ずしも一致するとは限りません。
文字コードによって、1文字あたりのバイト数が異なるからです。
例えば、英数字は1バイト、日本語のShift-JISは2バイト、UTF-8は1〜4バイトで表現されます。
○文字コードとバイト数の関係
文字コードは、文字をコンピュータで扱うために、各文字に番号を割り当てたものです。
代表的な文字コードには、次のようなものがあります。
- ASCII -> 英数字、記号など128文字を1バイトで表現
- Shift-JIS -> 日本語の文字を2バイトで表現
- UTF-8 -> 世界中の文字を1〜4バイトで表現
- UTF-16 -> 世界中の文字を2または4バイトで表現
文字コードによって、同じ文字でもバイト数が異なります。
そのため、バイト数を正確に求めるためには、文字コードを考慮する必要があります。
○サンプルコード7:Shift-JISでのバイト数カウント
ここでは、Shift-JISを想定した、バイト数をカウントするサンプルコードを紹介します。
この関数では、文字列を1文字ずつ確認し、その文字のUnicodeコードポイントを調べています。
Shift-JISでは、0から255までのコードポイントは1バイト、それ以外は2バイトで表現されます。
そのため、コードポイントが0から255の範囲内であれば1バイト、それ以外は2バイトとしてカウントしています。
サンプルコードの実行結果は29になります。
“こんにちは、JavaScript!”は、日本語の文字が9文字、英数字と記号が11文字で、合計29バイトとなります。
○サンプルコード8:UTF-8でのバイト数カウント
一方、UTF-8を想定したバイト数のカウントは、少し複雑になります。
UTF-8では、1文字が1〜4バイトで表現されるためです。
UTF-8でのバイト数カウントのサンプルコードをみてみましょう。
この関数では、Unicodeコードポイントの範囲に応じて、バイト数を判定しています。
- 0x80未満(0〜127) -> 1バイト
- 0x800未満(128〜2047) -> 2バイト
- 0x10000未満(2048〜65535) -> 3バイト
- それ以外(65536以上) -> 4バイト
サンプルコードの実行結果は38になります。
UTF-8では、日本語の文字は3バイトで表現されるため、日本語9文字で27バイト、英数字と記号が11バイトで、合計38バイトになります。
バイト数を考慮する場面は、主にデータの保存やネットワーク通信の際です。
例えば、データベースのフィールドにバイト数の上限がある場合や、ネットワークの通信量を削減したい場合などです。
また、メモリ使用量を正確に把握するためにも、バイト数を知ることが重要です。
特に、大量のデータを扱うアプリケーションでは、バイト数が性能に大きな影響を与えます。
●よくあるエラーと対処法
JavaScriptで文字数をカウントする際、いくつかの落とし穴があります。
ここでは、よくあるエラーとその対処法について見ていきましょう。
正しく文字数をカウントするためには、このエラーを理解し、適切に対処することが重要です。
○lengthプロパティが思った値を返さないケース
lengthプロパティは、文字列の長さを返すために使われますが、時として期待した値を返さないことがあります。
その代表的なケースが、サロゲートペアを含む文字列です。
サロゲートペアは、2つのコードユニットの組み合わせで表現される文字です。
lengthプロパティは、サロゲートペアを2文字としてカウントするため、見た目の文字数と異なる結果になることがあります。
例えば、次のようなコードを考えてみましょう。
この例では、絵文字の😊が1文字に見えますが、lengthプロパティは2を返します。
これは、😊がサロゲートペアで表現されているためです。
このようなケースでは、サロゲートペアを考慮したカウント関数を使う必要があります。
先述の「サロゲートペアに対応した文字数カウント」で紹介した関数を使えば、正しい文字数を求めることができます。
○サロゲートペアを考慮していないことによる不具合
サロゲートペアを考慮していないと、文字数のカウントだけでなく、文字列の操作全般で不具合が生じる可能性があります。
例えば、このようなコードを考えてみましょう。
この例では、strから先頭の5文字を切り出そうとしていますが、結果は期待通りになりません。
sliceメソッドは、サロゲートペアを考慮せずに文字列を切り出すため、絵文字が途中で切れてしまっています。
このような不具合を避けるためには、サロゲートペアを考慮した文字列操作が必要です。
正規表現を使って文字列を処理するのも1つの方法ですが、より確実なのは、専用のライブラリを使うことです。
例えば、「grapheme-splitter」というライブラリを使えば、サロゲートペアを考慮した文字列の分割ができます。
このように、適切なツールを使うことで、サロゲートペアによる不具合を回避することができます。
○正規表現の指定ミスでカウントがずれるパターン
正規表現を使った文字数カウントでは、正規表現の指定ミスによってカウントがずれることがあります。
例えば、次のようなコードを考えてみましょう。
この例では、小文字のアルファベットの数をカウントしようとしていますが、エラーが発生しています。
これは、strに小文字のアルファベットが含まれていないため、matchメソッドがnullを返すためです。
このようなエラーを避けるためには、正規表現にマッチしない場合の処理を追加する必要があります。
この例では、matchメソッドの結果がnullかどうかをチェックし、nullの場合は0を返すようにしています。
これで、正規表現にマッチしない場合でもエラーが発生しなくなります。
正規表現を使う際は、マッチしない場合の処理を忘れずに追加しましょう。
また、正規表現のパターンが意図通りかどうかも、よく確認する必要があります。
文字数カウントに限らず、JavaScriptでは様々なエラーに遭遇します。
エラーメッセージをよく読み、原因を特定することが大切です。
そして、エラーを適切に処理することで、安定したアプリケーションを作ることができます。
●文字数カウントの実践的な応用例
JavaScriptで文字数をカウントする方法を学んだら、実際のアプリケーション開発でそれを活用してみましょう。
文字数カウントは、ユーザー入力の制限やバリデーションなど、様々な場面で役立ちます。
ここでは、文字数カウントの実践的な応用例をいくつか見ていきます。
この例を通して、文字数カウントの活用方法を学び、自分のアプリケーションに取り入れる際のヒントにしてください。
○サンプルコード9:SNSの投稿文字数制限
SNSへの投稿では、文字数制限があることが一般的です。
TwitterではつぶやきをXXX文字以内に収める必要がありますし、InstagramやFacebookでも、あまりに長い投稿は読みづらくなってしまいます。
次のサンプルコードは、SNSの投稿文字数制限を実装した例です。
このコードでは、<textarea>
のmaxlength
属性で最大文字数を設定しています。
また、JavaScriptを使って、入力された文字数をカウントし、残り文字数を表示しています。
input
イベントを監視し、入力があるたびに文字数をチェックしています。
残り文字数がマイナスになった場合は、slice()
メソッドを使って文字列を切り詰め、最大文字数以内に収めています。
○サンプルコード10:コンタクトフォームの入力チェック
コンタクトフォームでは、ユーザーに適切な情報を入力してもらう必要があります。
例えば、名前やメールアドレスは必須項目であり、メッセージは一定の文字数以上であることが求められます。
次のサンプルコードは、コンタクトフォームの入力チェックを実装した例です。
このコードでは、<input>
と<textarea>
のrequired
属性を使って、必須項目を設定しています。
また、<textarea>
のminlength
属性で、最小文字数を設定しています。
JavaScriptでは、input
イベントを監視し、入力された文字数をチェックしています。
文字数が100文字未満の場合は、setCustomValidity()
メソッドを使ってカスタムエラーメッセージを設定しています。
submit
イベントを監視し、フォームの入力に誤りがある場合は、preventDefault()
メソッドを使ってフォームの送信を中止し、エラーメッセージを表示しています。
○文字数を利用したランダム文字列の生成
文字数カウントは、ランダムな文字列を生成する際にも活用できます。
例えば、パスワードのリセットやワンタイムトークンの発行など、一定の文字数のランダムな文字列が必要になることがあります。
次のサンプルコードは、文字数を指定してランダムな文字列を生成する例です。
この関数では、英数字からなる文字列を用意し、指定された文字数分だけランダムに文字を選んで結合しています。
Math.random()
で0から1までのランダムな数値を生成し、Math.floor()
で整数に切り捨てることで、ランダムなインデックスを取得しています。
まとめ
JavaScriptで文字数をカウントする方法について、基本から応用まで幅広く解説しました。
lengthプロパティの使い方、全角半角の判定、サロゲートペアへの対応、正規表現の活用など、正確に文字数をカウントするためのポイントを押さえることができたかと思います。
本記事で解説した知識を活かすことで、より洗練されたアプリケーションを作ることができるでしょう。