半角カナ混じりの文字幅を数える

文字幅ってどうやって調べるんだろって思って、
使えるモジュールを探してみた。

#!/usr/bin/env perl
use strict;
use warnings;
use utf8;

my $str = "リンゴゴリラ";

{
    use Unicode::Japanese;
    printf "[%s] length = %d\n",
        'Unicode::Japanese', Unicode::Japanese->new($str)->strlen;
}

{
    use Text::VisualWidth::UTF8;
    printf "[%s] length = %d\n",
        'Text::VisualWidth', Text::VisualWidth::UTF8::width($str);
}

{
    use Unicode::EastAsianWidth;

    my $count_length = sub {
        my $str = shift;
        my $count = 0;

        while ($str =~ m{(?:(\p{InFullwidth})|(\p{InHalfwidth}))}g) {
            if (defined $1) {
                $count += 2;
            } else {
                $count += 1;
            }
        }

        return $count;
    };

    printf "[%s]length = %d\n",
        'Unicode::EastAsianWidth', $count_length->($str);
}

結果は以下のとおり。

[Unicode::Japanese] length = 16
[Text::VisualWidth] length = 8
[Unicode::EastAsianWidth]length = 8

Unicode::Japaneseは半角カナを 2文字幅と誤って判定してしまうので、
使わない方がいいでしょう。


日本語以外でも使える Unicode::EastAsianWidthが良さそうです。