[date:20121212]の検索結果


Perlのlength関数ではバイト単位となるので、UTF-8でエンコードされている場合、漢字、ひらがな、カタカナなどは1文字で3となってしまいます。

ブログなどのアプリケーションのテキスト処理ではそれでは不都合な場合もことも多いので、半角英数も全角文字(漢字、ひらがな、カタカナなど) も1文字としてカウントする関数を作成することにします。

UTF-8では、

1バイト目の先頭ビットが0の場合は1バイト文字
1バイト目の先頭から3ビットが110の場合は2バイト文字
1バイト目の先頭から4ビットが1110の場合は3バイト文字
1バイト目の先頭から5ビットが11110の場合は4バイト文字
1バイト目の先頭から6ビットが111110の場合は5バイト文字
1バイト目の先頭から7ビットが1111110の場合は2バイト文字

という仕様ですので、1バイト目のビットの状態を調べることによって、その文字が何バイトかを調べることができます。

以下のコードでは、この仕様にもとづいて全角文字を含む文字列の文字数を取得しています。

#!/usr/bin/perl

use strict;
use warnings;

my $testAscii = "ABCDEFG";
my $testHira  = "あいうえお";
my $testKata  = "アイウエ";
my $testKanji = "愛々木";
my $testAll = "ABCDEFGあいうえおアイウエオ愛夢佐々木";

print "length($testAscii) = ".length($testAscii), "\n";
print "strlen_utf8($testAscii) = ".strlen_utf8($testAscii), "\n";

print "length($testHira) = ".length($testHira), "\n";
print "strlen_utf8($testHira) = ".strlen_utf8($testHira), "\n";

print "length($testKata) = ".length($testKata), "\n";
print "strlen_utf8($testKata) = ".strlen_utf8($testKata), "\n";

print "length($testKanji) = ".length($testKanji), "\n";
print "strlen_utf8($testKanji) = ".strlen_utf8($testKanji), "\n";

print "length($testAll) = ".length($testAll), "\n";
print "strlen_utf8($testAll) = ".strlen_utf8($testAll), "\n";

exit;

# UTF-8でエンコードされた文字列の文字数を取得する。
sub strlen_utf8 {
    my ($text) = @_;

    my $textlen = length($text);
    my $pos = 0;
    my $count = 0;

    while ($pos < $textlen) {
        my $code = ord substr($text, $pos, 1); # 先頭のASCIIコード値を取得
        my $bytelen = _bytesize($code);
        $pos += $bytelen;
        $count++; # 文字数をカウント
    }

    return $count;
}

# 文字のバイト長を求める
sub _bytesize {
    my ($code) = @_;
    my $size = 1;
    if (0x80 & $code) { # 1バイト文字以外
        $size++;
        $code <<= 1;
        for my $i (2 .. 8) {
            last if (!(0x80 & $code));
            $size++;
            $code <<= 1;
        }
    }
    return $size;
}

strlen_utf8関数では、substr関数を使用して1バイト目のASCIIコード値を取得し、 _bytesize関数を呼び出して文字のバイト数を求め、1文字分の処理を行うたびに文字数をカウントアップしています。

_bytesize関数ではパラメータで渡されたコード値の場合の文字のバイト数を、コード値のビットの状態から判定し 戻り値として返しています。

ゼロからわかる Perl言語超入門
技術評論社 著者:高橋 順子


amazon.co.jpのカスタマーレビューを見る
powered by amalink

[2243] Posted by kagahiro at 2012/12/12 11:56:21
1 point | Link (3) | Trackback (0) | Comment (1)

  1  


アクセスランキング

今日のアクセスランキング TOP 10

  1. SQLのSELECT文で先頭から上位(TOP)10件のレコードを取得する方法(SQL Server、Oracle、MySQL、PostgreSQL) (22 PV)
  2. FC2まとめ (5 PV)
  3. Google Finance(グーグルファイナンス)- リアルタイム株価情報、金融ニュース、日本株 (4 PV)
  4. StartPage(スタートページ) - 匿名検索エンジン (3 PV)
  5. Google Maps(グーグルマップ)日本版 - 地図検索、ルート検索 (2 PV)
  6. [ch225] 「世界の株価リアルタイムチャート」 (2 PV)
  7. Perlで全角半角変換を行う方法 (1 PV)
  8. IBM、開発者向けに無償版データベースソフト「IBM Db2 Developer Community Edition」を公開 #プログラミング (1 PV)
  9. 海外掲示板を読むために気になったスラング系英単語まとめ | Kousyoublog (1 PV)
  10. アルファブロガーを取込めばブログ界を支配できる (1 PV)

今月のアクセスランキング TOP 10

  1. SQLのSELECT文で先頭から上位(TOP)10件のレコードを取得する方法(SQL Server、Oracle、MySQL、PostgreSQL) (91 PV)
  2. FC2まとめ (38 PV)
  3. 海外掲示板を読むために気になったスラング系英単語まとめ | Kousyoublog (33 PV)
  4. 2NN 2ちゃんねるニュース速報+ナビ (29 PV)
  5. Google Finance(グーグルファイナンス)- リアルタイム株価情報、金融ニュース、日本株 (22 PV)
  6. StartPage(スタートページ) - 匿名検索エンジン (15 PV)
  7. MT4向け無料ヘッジ(両建て)ツール(EA)「STOPPER FREE」 #自動売買 #FX (15 PV)
  8. SQLiteのSELECT文で上位 (TOP) n件のデータを取得する (12 PV)
  9. [gcc]iconvで文字エンコードを変換するサンプルプログラム (11 PV)
  10. Google Maps(グーグルマップ)日本版 - 地図検索、ルート検索 (11 PV)

アクセス統計

ディレクトリ

関連サイト