7
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【初心者向け】Ruby のまずいコード 25 本Advent Calendar 2021

Day 25

【Ruby のまずいコード】漢字を数える

Posted at

お題

引数として与えられた文字列中の漢字の個数を数えて返すメソッドを書いてください。
同じ漢字が複数回出てきてもそれぞれカウントします。
文字列は 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 というメソッドがあります。
これを使うと,たとえば az および AZ の個数を数えるのは

str.count("a-zA-Z")

のように書けます。
(ベンチマークテストはしていませんが)scan して count するよりも速いと思います。

ただ,String#count は正規表現が使えません。これで漢字を数えようとすると,Unicode 上のすべての漢字の範囲を調べて書く必要があり,少々面倒です。

7
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?