JavaScript Tips | 文字列ユーティリティ:生成 - 単語数カウント

JavaScript JavaScript
スポンサーリンク

「単語数カウント」で何を数えたいのかを決める

まず、ここをはっきりさせたいです。
「単語数を数える」と言っても、言語や用途で意味が変わります。

英語の文章なら、スペースで区切られた「単語」を数えたい。
日本語の文章なら、「単語」というより「英単語だけ数えたい」「タグの数を数えたい」など、目的が変わる。

ここでは、まず「英語などの“スペース区切りの単語”を数える」パターンを押さえつつ、
日本語を含むテキストで「英単語だけ数える」実務寄りの形まで持っていきます。


一番基本の「スペースで区切って数える」単語カウント

まずはシンプルな版から

英語だけの文章なら、「空白で区切って、空じゃない要素を数える」だけで、かなり実用的です。

function countWordsSimple(text) {
  if (text == null) return 0;

  const s = String(text).trim();

  if (s === "") return 0;

  const parts = s.split(/\s+/);

  return parts.length;
}
JavaScript

ここが重要ポイントです。

trim() で前後の空白を削っておく(先頭・末尾の空白で余計な空要素ができるのを防ぐ)。
\s+ は「1つ以上の空白(スペース、タブ、改行など)」という意味。
split(/\s+/) で「空白で区切られたかたまり」を配列にする。
配列の長さが、そのまま「単語数」になる。

動きのイメージはこうです。

countWordsSimple("Hello world");              // 2
countWordsSimple("  Hello   world  ");        // 2
countWordsSimple("This is a pen.");           // 4
countWordsSimple("line1\nline2 line3");       // 3
countWordsSimple("");                         // 0
JavaScript

英語だけの入力欄や、タグをスペース区切りで入力させるような場面なら、まずこのレベルで十分です。


「英単語だけ数えたい」実務寄りのパターン

日本語と英語が混ざるテキスト

日本語の文章には、英単語が混ざることがよくあります。

これは JavaScript の word count ユーティリティです

このとき、「英単語だけ何個あるか」を知りたいことがあります。
例えば、

英単語の数で難易度をざっくり測る。
英単語だけを対象にした制限(「英単語は最大 50 個まで」など)をかける。

こういうときは、「英単語っぽいものだけを拾う」正規表現を使うのが現実的です。

英単語だけを数えるユーティリティ

function countEnglishWords(text) {
  if (text == null) return 0;

  const s = String(text);

  const matches = s.match(/[A-Za-z]+/g);

  if (!matches) return 0;

  return matches.length;
}
JavaScript

ここが重要ポイントです。

[A-Za-z]+ は「英字が1文字以上続くかたまり」を表す。
match(..., "g") で、テキスト中のすべての「英字のかたまり」を配列として取得する。
見つからなければ null が返るので、その場合は 0。
見つかった場合は、その配列の長さが「英単語の数」とみなせる。

動きはこうなります。

countEnglishWords("これは JavaScript の word count ユーティリティです");
// 2("JavaScript", "word")

countEnglishWords("HTML CSS JS");
// 3

countEnglishWords("英語なしの文章です");
// 0
JavaScript

「英単語だけを対象にしたカウント」が欲しいときは、この形がシンプルで分かりやすいです。


タグ入力など「区切り文字で数える」パターン

カンマ区切り・スペース区切りのタグ

実務でよくあるのが、「タグを区切り文字で入力させる」パターンです。

tag1 tag2 tag3
tag1, tag2, tag3

この場合、「単語」というより「区切り文字で分割した要素数」を数えたい、という話になります。

区切り文字を指定できる汎用カウンタ

function countTokens(text, separatorPattern = /[,\s]+/) {
  if (text == null) return 0;

  const s = String(text).trim();

  if (s === "") return 0;

  const parts = s.split(separatorPattern);

  const tokens = parts.filter((p) => p !== "");

  return tokens.length;
}
JavaScript

ここがポイントです。

separatorPattern に「区切り文字の正規表現」を渡せるようにしている。
デフォルトは /[,\s]+/ で、「カンマまたは空白が1つ以上続くところ」で区切る。
filter で空文字を除外してから数える。

動きはこうなります。

countTokens("tag1 tag2 tag3");          // 3
countTokens("tag1,tag2, tag3");         // 3
countTokens("  tag1 ,  tag2 , tag3 ");  // 3

// セミコロン区切りにしたい場合
countTokens("a;b;c", /[;]+/);           // 3
JavaScript

「タグ数」「キーワード数」「IDリストの要素数」など、
“区切り文字で分けられたものの数”を数えたいときに、そのまま使えます。


実務での使いどころと設計のポイント

「何を単語とみなすか」を先に決める

単語数カウントは、一見シンプルですが、
「何を1単語とみなすか」で結果が変わる処理です。

スペースで区切られたかたまり全部を単語とみなすのか。
英字だけを単語とみなすのか。
カンマやセミコロンなど、特定の区切り文字で分けられたものを数えるのか。

これを画面ごと・機能ごとにバラバラに決め始めると、
「ここでは 10 単語までOKなのに、あっちでは 9 でエラーになる」といったズレが出ます。

だからこそ、

export function countWordsSimple(...) { ... }   // 空白区切りの単語数
export function countEnglishWords(...) { ... }  // 英単語だけ
export function countTokens(...) { ... }        // 区切り文字で分けた要素数
JavaScript

のように、目的ごとに関数を分けておくのがきれいです。

バリデーションとセットで使う

例えば、「キーワードは最大 10 個まで」といった制限なら、こう書けます。

const maxKeywords = 10;
const value = keywordsInput.value;
const count = countTokens(value);

if (count > maxKeywords) {
  showError(`キーワードは最大 ${maxKeywords} 個までです(現在 ${count} 個)。`);
}
JavaScript

「今いくつ使っているか」を一緒に見せてあげると、ユーザーにも親切です。


ちょっとだけ手を動かしてみる

コンソールで、次のあたりを試してみてください。

countWordsSimple("This is a pen.");
countWordsSimple("  This   is   a   pen.  ");

countEnglishWords("これは JavaScript の word count ユーティリティです");

countTokens("tag1 tag2 tag3");
countTokens("tag1, tag2, tag3");
JavaScript

「どのケースで何個と数えられるか」を、自分の目で確かめてみてください。

そのうえで、自分のプロジェクトに

export function countWordsSimple(...) { ... }
export function countEnglishWords(...) { ... }
export function countTokens(...) { ... }
JavaScript

の3本を置いて、

英語の文章 → countWordsSimple
英単語だけ数えたい → countEnglishWords
タグ・キーワード → countTokens

という使い分けをルール化してみてください。

それだけで、あなたの「単語数カウント」は
なんとなくの split(" ") から、
目的と入力の実態をちゃんと意識した“業務レベルのユーティリティ”に一段レベルアップします。

タイトルとURLをコピーしました