お題
引数として与えられた文字列中の漢字の個数を数えて返すメソッドを書いてください。
同じ漢字が複数回出てきてもそれぞれカウントします。
文字列は UTF-8 であるとします。
コード
def kanji_count(str)
str.scan(/[一-龥]/).count
end
講評
「すべての漢字」を表す正規表現として [一-龥]
は使えません。これでは Unicode の漢字の一部分しか拾えません。
Unicode では,漢字がいくつものブロックに分かれて収録されていますが,そのうちの最も基本的なものが「CJK 統合漢字(CJK Unified Ideographs)」と呼ばれるブロックです。
CJK 統合漢字のブロックは,Unicode バージョン 1.0 のとき,「一」で始まり「龥」で終わっていました。
[一-龥]
という正規表現はその時代(30 年前!)の名残でしょう。
改善
「すべての漢字」を表す文字クラスは \p{Han}
と書けます。これを使うのが簡単です。
def kanji_count(str)
str.scan(/\p{Han}/).count
end
なお,特定範囲の文字の個数を数えるのに String#count というメソッドがあります。
これを使うと,たとえば a
〜z
および A
〜Z
の個数を数えるのは
str.count("a-zA-Z")
のように書けます。
(ベンチマークテストはしていませんが)scan
して count
するよりも速いと思います。
ただ,String#count
は正規表現が使えません。これで漢字を数えようとすると,Unicode 上のすべての漢字の範囲を調べて書く必要があり,少々面倒です。