[部分文字列]の検索結果


C言語のstrncpy関数やmemcpy関数ではバイト単位の操作になるので、漢字、ひらがな、カタカナなどの全角文字を文字数で指定して部分文字列を取り出すことができません。 そこで半角英数も全角文字も1文字として部分文字列を取り出すことができる関数を作成します。

以下はそのコードです。[C言語]UTF-8でエンコードされた文字列の文字数を取得するコードと同様に、文字の1バイト目のビットの状態を調べることによってその文字が何バイト文字を判定しています。

#include <stdio.h>
#include <string.h>

char *substr_utf8(char *dest, char *src, int offset, int len);
int _bytesize(unsigned char code);


int main(void)
{
    char *testStr = "ABCDEFGあいうえおアイウエオ愛夢佐々木";
    char strBuf[256];

    memset(strBuf, 0sizeof strBuf);

    printf("substr_utf8($testStr, 0, 5) = %s\n", substr_utf8(strBuf, testStr, 05));
    printf("substr_utf8($testStr, 3, 3) = %s\n", substr_utf8(strBuf, testStr, 33));
    printf("substr_utf8($testStr, 10, 4) = %s\n", substr_utf8(strBuf, testStr, 104));
    printf("substr_utf8($testStr, 13, 5) = %s\n", substr_utf8(strBuf, testStr, 135));

    return 0;
}

/* UTF-8でエンコードされた文字列の部分文字列を取り出す */
/* substr_utf8 (文字列式, オフセット, 長さ)*/
char *substr_utf8(char *dest, char *src, int offset, int len)
{
    int srclen = strlen(src);
    int pos = 0;
    int count = 0;
    char *cp = dest;

    while (pos < srclen) {
        unsigned char code;
        code = *(src + pos); /* ASCIIコード値を取得 */
        int bytelen = _bytesize(code);

        if (count >= offset && count < (offset + len)) {
            memcpy(cp, (src + pos), bytelen);
            cp += bytelen;
            *cp = '\0';
        }
        pos += bytelen;
        count++; /* 文字数をカウント */
    }

    return dest;
}

/* 文字のバイト長を求める */
int _bytesize(unsigned char code)
{
    int size = 1;
    int i;

    if (0x80 & code) { /* 1バイト文字以外 */
        for (i = 2; i <= 8; i++) {
            code <<= 1;
            if (!(0x80 & code)) {
                break;
            }
            size++;
        }
    }
    return size;
}

実行結果
$ ./substr_utf8
substr_utf8($testStr, 0, 5) = ABCDE
substr_utf8($testStr, 3, 3) = DEF
substr_utf8($testStr, 10, 4) = えおアイ
substr_utf8($testStr, 13, 5) = イウエオ愛

[2324] Posted by kagahiro at 2013/07/02 11:02:48
0 point | Link (3) | Trackback (0) | Comment (0)

Perlのsubstr関数ではバイト単位の操作になるので、漢字、ひらがな、カタカナなどの全角文字を文字数で指定して部分文字列を取り出すことができません。それでは不都合なことも多いので、半角英数も全角文字も1文字として部分文字列を取り出すことができる関数を作成します。

以下はそのコードです。[Perl]UTF-8でエンコードされた文字列の文字数を取得するコードと同様に、文字の1バイト目のビットの状態を調べることによってその文字が何バイト文字を判定しています。

#!/usr/bin/perl

use strict;
use warnings;

my $testStr = "ABCDEFGあいうえおアイウエオ愛夢佐々木";

print "substr_utf8($testStr, 0, 5) = " . substr_utf8($testStr, 0, 5), "\n";
print "substr_utf8($testStr, 3, 3) = " . substr_utf8($testStr, 3, 3), "\n";
print "substr_utf8($testStr, 10, 4) = " . substr_utf8($testStr, 10, 4), "\n";
print "substr_utf8($testStr, 13, 5) = " . substr_utf8($testStr, 13, 5), "\n";
print "substr_utf8($testStr, 13) = " . substr_utf8($testStr, 13), "\n";

exit;

# UTF-8でエンコードされた文字列の部分文字列を取り出す
# substr_utf8 (文字列式, オフセット[, 長さ])長さを指定しなかった場合は最後まで
sub substr_utf8 {
    my ($src, $offset, $len) = @_;

    my $srclen = length($src);
    my $pos = 0;
    my $count = 0;
    my $dest = '';

    while ($pos < $srclen) {
        my $code = ord substr($src, $pos, 1); # 先頭のASCIIコード値を取得
        my $bytelen = _bytesize($code);
        if (defined($len)){
            if ($count >= $offset && $count < ($offset + $len)) {
                $dest .= substr($src, $pos, $bytelen);
            }
        } else { # 長さ指定なし
            if ($count >= $offset) {
                $dest .= substr($src, $pos, $bytelen);
            }
        }
        $pos += $bytelen;
        $count++; # 文字数をカウント
    }

    return $dest;
}

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

substr_utf8関数では、substr関数を使用して1バイト目のASCIIコード値を取得し、 _bytesize関数を呼び出して文字のバイト数を求め、その文字がパラメータで指定された範囲の場合は、戻り値として返す文字列に連結し、そうでなかった場合は文字数のカウントアップのみ行なっています。

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

もっと自在にサーバを使い倒す 業務に役立つPerl (Software Design plus)
技術評論社 著者:木本 裕紀


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

[2244] Posted by kagahiro at 2012/12/13 10:51:25
0 point | Link (4) | Trackback (0) | Comment (0)

  1  


アクセスランキング

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

  1. SQLのSELECT文で先頭から上位(TOP)10件のレコードを取得する方法(SQL Server、Oracle、MySQL、PostgreSQL) (40 PV)
  2. 2NN 2ちゃんねるニュース速報+ナビ (8 PV)
  3. 安全性重視の完全無料ナンピンマーチンEA「Million Dollar(ミリオンダラー)」 #FX #ゴールド #ビットコイン (5 PV)
  4. 2chまとめサイト - 痛いニュース(ノ∀`) (3 PV)
  5. SQLiteのSELECT文で上位 (TOP) n件のデータを取得する (2 PV)
  6. 無料のMT4向けナンピンマーチン爆益(爆損)EA「Jipangu(ジパング)」 (2 PV)
  7. 自作のMT4向け無料EA(口座縛り無し、ブローカー縛り無し、使用期限無し)とゴゴジャン出品中の有料EAの一覧 #MT4 (1 PV)
  8. ハイレバギャンブルトレードで爆益か爆損か? MT4向けの無料EA「10bagger(テンバガー)」 (1 PV)
  9. [FX]高値更新・安値更新でエントリー、MT4向け無料スキャルピングEA「1Scalper」#システムトレード (1 PV)
  10. [FX]裁量ポジションを簡単に管理できるMT4向け無料の裁量補助EA「PositionKeeper」 (1 PV)

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

  1. 2NN 2ちゃんねるニュース速報+ナビ (3273 PV)
  2. SQLのSELECT文で先頭から上位(TOP)10件のレコードを取得する方法(SQL Server、Oracle、MySQL、PostgreSQL) (488 PV)
  3. 安全性重視の完全無料ナンピンマーチンEA「Million Dollar(ミリオンダラー)」 #FX #ゴールド #ビットコイン (91 PV)
  4. 自作のMT4向け無料EA(口座縛り無し、ブローカー縛り無し、使用期限無し)とゴゴジャン出品中の有料EAの一覧 #MT4 (87 PV)
  5. SQLiteのSELECT文で上位 (TOP) n件のデータを取得する (70 PV)
  6. Million Dollar Ver 1.09向けの収益性を重視したゴールド(Gold、XAUUSD)ロングセットファイル (64 PV)
  7. 無料のMT4向けナンピンマーチン爆益(爆損)EA「Jipangu(ジパング)」 (60 PV)
  8. 仲値トレードが簡単にできる無料EA「NAKANE3 Ver 2.04」 #MT4 (58 PV)
  9. [FX]裁量ポジションを簡単に管理できるMT4向け無料の裁量補助EA「PositionKeeper」 (49 PV)
  10. 2chまとめサイト - 痛いニュース(ノ∀`) (46 PV)

アクセス統計

ディレクトリ

関連サイト