他のシステムとの連携や、何だかんだ印刷時には気になるということで、半角だと1、全角だと2文字として数えたいときってありますよね。
新バージョン (6/4 追記)
なんか以下の様なコードの方が良い気がしてきました。 ロクに確認してないけど、圧倒的に速いはずです。
better_helper.rb
class String
def better_han_zen_length
self.length*2 - self.scan(/[0-9a-zA-Z]+/).join.length
end
end
ベンチマークで比較してみた (6/16 追記)
benchmark.rb
a = "あふぁsぢsふぃあwふgyfsidfuhierigfs98ふぁいsdbしあうyfdg981798171あいうはしfはすfぎうあygsf198y19いうfはいあshf8さぎfばsdf198y19hisjfoasf:;l^-0o:f;sd912obakjfiahf"
n = 100000
Benchmark.bm do |x|
x.report { n.times{ a.han_zen_length } }
x.report { n.times{ a.better_han_zen_length } }
end
user system total real
14.860000 0.060000 14.920000 ( 14.925007)
1.040000 0.010000 1.050000 ( 1.052821)
環境はMacBook Air 11-inch Mid 2013, 4GB RAM, 1.3GHz Intel Corei5 といったあたりです。
予想通り better_の方がずっと良い、という事ですね。
以前のバージョン
以下のようなコードで、一応数えれるよね。 という。
helper.rb
class String
def han_zen_length
regexp = /[0-9a-zA-Z]/
return chars.map do |c|
if c.match(regexp)
1
else
2
end
end.sum
end
end
こんな感じにしておいて、以下の様な実行結果が得られます。めでたしめでたし。
"ほげab".han_zen_length
#=> 6
- 動作は(案外)重くないですが、大量に処理する時は、もっと高度な方策を考えた方が良いかも知れません。
- 正規表現が非常にいい加減なので、クリティカルなケースでは記号とか追加してあげてください。