Java Tips | 文字列処理:単語数カウント

Java Java
スポンサーリンク

単語数カウントは「文章を“意味のかたまり”として扱う」ための基礎技術

単語数カウントは、文章を「いくつの単語で構成されているか」を調べる処理です。
英語の文章解析、検索キーワードの処理、タグ入力のチェック、ログ解析など、業務でも意外と出番があります。

そして、単語分割と同じく 「何を単語とみなすか」 を決めることが最重要ポイントです。
ここを曖昧にしたまま実装すると、後で必ずズレが出ます。


まずは基本:空白区切りで単語数を数える

最もシンプルな単語数カウント

英語やスペース区切りの入力では、
「空白で区切られたもの=単語」とみなすのが基本です。

public final class WordCountUtil {

    private WordCountUtil() {}

    public static int countBySpace(String text) {
        if (text == null || text.isBlank()) {
            return 0;
        }
        String[] words = text.trim().split(" ");
        return words.length;
    }
}
Java

使い方はこうなります。

System.out.println(WordCountUtil.countBySpace("I love Java")); // 3
System.out.println(WordCountUtil.countBySpace("Hello World")); // 2
System.out.println(WordCountUtil.countBySpace(""));            // 0
System.out.println(WordCountUtil.countBySpace(null));          // 0
Java

ここで押さえておきたいポイントは二つです。

1つ目:null や空文字は 0 とみなす方針を決めていること。
これにより、呼び出し側で毎回 null チェックを書く必要がなくなります。

2つ目:trim() を使って前後の空白を落としていること。
これをしないと、先頭や末尾の空白が原因で空文字がカウントされてしまいます。

ただし、この実装には弱点があります。
スペースが連続すると、空文字が単語としてカウントされてしまうのです。


実務で使うなら:split("\s+") で「連続する空白」を1つの区切りにする

空白が複数あっても正しく単語数を数える

業務データでは、スペースが1つとは限りません。
タブが混ざることもあります。

そこで使うのが正規表現 \\s+(空白1つ以上)です。

public final class WordCountUtil {

    private WordCountUtil() {}

    public static int countByWhitespace(String text) {
        if (text == null || text.isBlank()) {
            return 0;
        }
        String[] words = text.trim().split("\\s+");
        return words.length;
    }
}
Java

使い方はこうです。

System.out.println(WordCountUtil.countByWhitespace("I   love Java")); // 3
System.out.println(WordCountUtil.countByWhitespace("  I\tlove   Java ")); // 3
Java

ここで深掘りしたい重要ポイントは三つです。

1つ目:isBlank() を使って「空白だけの文字列」を 0 とみなしていること。
isEmpty() だと " " が単語1つと誤判定されます。

2つ目:trim() で前後の空白を削除していること。
これにより、先頭や末尾の空白が単語数に影響しません。

3つ目:"\\s+" により、スペース・タブ・改行などの「空白文字」をまとめて扱えること。
業務データはきれいとは限らないので、これが非常に効きます。


記号を含む単語をどう扱うかを決める

「Java,」や「programming.」を1単語とみなすか?

英語の文章では、単語の後ろに記号がつくことがあります。

"Java,"
"programming."

split("\\s+") ではこれらはそのまま1単語として扱われます。

String text = "I love Java, programming.";
System.out.println(WordCountUtil.countByWhitespace(text)); // 4
Java

これで問題ない場面も多いですが、
「記号を除いた純粋な単語数を数えたい」という要件もあります。

その場合は、分割後に記号を除去します。

public static int countWithoutPunctuation(String text) {
    if (text == null || text.isBlank()) {
        return 0;
    }
    String[] raw = text.trim().split("\\s+");
    int count = 0;
    for (String w : raw) {
        String cleaned = w.replaceAll("^[\\p{Punct}]+|[\\p{Punct}]+$", "");
        if (!cleaned.isEmpty()) {
            count++;
        }
    }
    return count;
}
Java

使い方はこうです。

System.out.println(countWithoutPunctuation("I love Java, programming.")); // 4
Java

ここでの重要ポイントは、
「分割」と「正規化(クリーニング)」を分けて考えること です。

単語分割 → 記号除去 → 単語数カウント
という流れを意識すると、処理が整理されます。


日本語の「単語数カウント」は別物だと理解する

日本語はスペースで区切られない

英語はスペースで単語が区切られますが、
日本語は "私はJavaが好きです" のようにスペースが入りません。

この場合、単語数カウントは「形態素解析」という別の技術が必要になります。
MeCab や Kuromoji などのライブラリを使う世界です。

今回のユーティリティは、
スペース区切りの単語数カウント(英語・タグ・キーワード入力など)
を対象にしていると理解してください。


実務での単語数カウントの使いどころ

例1:検索キーワードの個数チェック

「検索キーワードは最大5個まで」という要件があるとします。

String input = request.getParameter("q");
int count = WordCountUtil.countByWhitespace(input);

if (count > 5) {
    errors.add("検索キーワードは5個以内で指定してください。");
}
Java

ここでのポイントは、
「空白の揺れ(スペース連続・タブ混入)に強い」 ことです。

例2:タグ入力の個数制限

「タグはスペース区切りで最大10個まで」という画面もよくあります。

String tags = request.getParameter("tags");
if (WordCountUtil.countByWhitespace(tags) > 10) {
    errors.add("タグは10個以内で入力してください。");
}
Java

例3:文章の単語数を集計してレポートに使う

ログ解析や文章解析で、単語数を集計する場面もあります。

String text = logEntry.getMessage();
int wordCount = WordCountUtil.countByWhitespace(text);
Java

まとめ:単語数カウントユーティリティで身につけたい感覚

単語数カウントは、単純に見えて奥が深い処理です。
実務で役立つユーティリティにするには、次の感覚が重要です。

空白1個ではなく「空白1つ以上」で区切る
trim()isBlank() で前後の空白や空白だけの入力を正しく扱う
必要に応じて記号を除去する
日本語の単語数カウントは別技術(形態素解析)であると理解する

もしあなたのコードのどこかに、

text.split(" ").length
Java

のような行がそのまま書かれていたら、
それを split("\\s+") を使ったユーティリティに置き換えてみてください。

その小さな改善が、
「入力の揺れに強く、後続処理が安定する文字列ユーティリティ」を扱えるエンジニアへの確かな一歩になります。

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