[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) (19 PV)
  2. [将棋]竜王戦第三局は居飛車振り飛車の対抗型で丸山忠久九段が勝利 #竜王戦 (18 PV)
  3. フリーソフトウェア/オープンソースのタブー (17 PV)
  4. [食べ物]七草粥(ななくさがゆ) (16 PV)
  5. グーグルニュース(Google News)日本語版が表示されるURL (15 PV)
  6. Google News (グーグルニュース)日本版 (12 PV)
  7. [将棋]将棋実況ユーチューバーのクロノさんが朝日新聞のクレームで棋譜中継を配信中止 (8 PV)
  8. [Perl]UTF-8でエンコードされた文字列の文字数を取得するコード (7 PV)
  9. ようつべ (YouTube) 動画のダウンロードと保存 (5 PV)
  10. さくらインターネット、さくらのVPSスタートアップスクリプトに無料SSLサーバー証明書「Let's Encrypt」を提供開始 (5 PV)

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

  1. SQLのSELECT文で先頭から上位(TOP)10件のレコードを取得する方法(SQL Server、Oracle、MySQL、PostgreSQL) (3005 PV)
  2. グーグルニュース(Google News)日本語版が表示されるURL (787 PV)
  3. フリーソフトウェア/オープンソースのタブー (540 PV)
  4. [食べ物]七草粥(ななくさがゆ) (522 PV)
  5. [将棋]竜王戦第三局は居飛車振り飛車の対抗型で丸山忠久九段が勝利 #竜王戦 (513 PV)
  6. Google News (グーグルニュース)日本版 (490 PV)
  7. [将棋]将棋実況ユーチューバーのクロノさんが朝日新聞のクレームで棋譜中継を配信中止 (236 PV)
  8. USTREAM(ユーストリーム) 日本語版 無料のライブ映像配信サービス (177 PV)
  9. グーグルニュース(Google News)のRSS/atomが取得できない (171 PV)
  10. [Perl]UTF-8でエンコードされた文字列の文字数を取得するコード (154 PV)

アクセス統計

ディレクトリ

関連サイト