[Perl]UTF-8でエンコードされた英数字の全角半角変換を行うコード

まずカタカナより比較的プログラミングしやすそうな英数字の全角半角変換から作成します。

半角から全角への変換の処理手順は、

・半角英数字の場合は、同じ全角英数字に置き換えて戻り値として返す文字列に連結
・それ以外の文字の場合はそのまま戻り値として返す文字列に連結

また、全角から半角への変換の処理手順は、

・全角英数字の場合は、同じ半角英数字に置き換えて戻り値として返す文字列に連結
・それ以外の文字の場合はそのまま戻り値として返す文字列に連結

となります。

文字コードはそれぞれ以下の通りですので、これらに該当する文字があったら置き換えを行います。

半角数字:0 - 9
30 - 39

全角数字:0 - 9
EFBC90 - EFBC99
2バイト目まではEFBC

半角アルファベット大文字:A - Z
41 - 5A

全角アルファベット大文字:A - Z
EFBCA1 - EFBCBA
2バイト目まではEFBC

半角アルファベット小文字:a - z
61 - 7A

全角アルファベット小文字:a - z
EFBD80 - EFBD9A
2バイト目まではEFBD

以下が英数字の半角から全角へ、全角から半角への変換を行うコード(プログラム)です。

#!/usr/bin/perl

use strict;
use warnings;
use Encode;

my $hanAlnum = "ABCDEい12345あabcde";
my $zenAlnum = "ABCDEい12345あabcdeカ";

my $zenstr = han2zen_alnum($hanAlnum);
Encode::from_to($hanAlnum, 'utf8', 'cp932');
Encode::from_to($zenstr, 'utf8', 'cp932');
print "$hanAlnum ---> $zenstr\n";

my $hanstr = zen2han_alnum($zenAlnum);
Encode::from_to($zenAlnum, 'utf8', 'cp932');
Encode::from_to($hanstr, 'utf8', 'cp932');
print "$zenAlnum ---> $hanstr\n";

# UTF-8でエンコードされた半角英数字を全角英数字に変換する
sub han2zen_alnum {
    my ($src) = @_;

    my $srclen = length($src);
    my $pos = 0;
    my $dest = '';
    while ($pos < $srclen) {
        my $code = ord substr($src, $pos, 1); # 先頭のASCIIコード値を取得
        my $bytelen = _bytesize($code);

        my $lastbyte = 0;
        my $bytechar = '';
        my $flagged_utf8 = ''; 
        if ($code >= 0x30 && $code <= 0x39) { # 数字
            $lastbyte = 0x90 + ($code - 0x30);
            $bytechar = pack("C3", 0xEF, 0xBC, $lastbyte);
            $dest .= $bytechar;
        }
        elsif ($code >= 0x41 && $code <= 0x5A) { # 大文字英字
            $lastbyte = 0xA1 + ($code - 0x41);
            $bytechar = pack("C3", 0xEF, 0xBC, $lastbyte);
            $dest .= $bytechar;
        
        }
        elsif ($code >= 0x61 && $code <= 0x7A) { # 小文字英字
            $lastbyte = 0x81 + ($code - 0x61);
            $bytechar = pack("C3", 0xEF, 0xBD, $lastbyte);
            $dest .= $bytechar;
        }
        else {
            $dest .= substr($src, $pos, $bytelen);
        }
        $pos += $bytelen;
    }

    return $dest;
}

# UTF-8でエンコードされた全角英数字を半角英数字に変換する
sub zen2han_alnum {
    my ($src) = @_;

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

    while ($pos < $srclen) {
        my $code = ord substr($src, $pos, 1); # 先頭のASCIIコード値を取得
        my $bytelen = _bytesize($code);
        my $hit = 0;
        if ($code == 0xEF) { # 全角英数の場合は1バイト目がEF
            my $code2 = ord substr($src, $pos + 1, 1);  # 2バイト目
            my $code3 = ord substr($src, $pos + 2, 1);  # 3バイト目
            if ($code2 == 0xBC) {
                if ($code3 >= 0x90 && $code3 <= 0x99) {
                    $dest .= chr(0x30 + ($code3 - 0x90));
                    $hit = 1;
                }
                elsif ($code3 >= 0xA1 && $code3 <= 0xBA) {
                    $dest .= chr(0x41 + ($code3 - 0xA1));
                    $hit = 1;
                }
            }
            elsif ($code2 == 0xBD) {
                if ($code3 >= 0x80 && $code3 <= 0x9A) {
                    $dest .= chr(0x61 + ($code3 - 0x80));
                    $hit = 1;
                }
            }
        }
        if(!$hit) {
            $dest .= substr($src, $pos, $bytelen);
        }
        $pos += $bytelen;
    }

    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;
}

[2250] Posted by kagahiro at 2012/12/19 16:54:42
オープン | 0 point | Link (1) | Trackback (0) | Comment (0)

キーワード

Perl 全角 半角 変換 表示 日本語 

ジャパンのホームページ


[Perl]UTF-8でエンコードされた英数字の全角半角変換を行うコード 関連リンク

Perlで全角半角変換を行う方法
日本語の文章では半角の英数字と全角の英数字、また、半角のカタカナと全角のカタカナが混在していることがよくあります。意味は半角でも全角でも同じですので、コンピュータで処理する場合はどちらかに統一してから...

[Perl]UTF-8でエンコードされた英数字の全角半角変換を行うコード トラックバック

トラックバックURL :


[Perl]UTF-8でエンコードされた英数字の全角半角変換を行うコードへのコメント


詳細の入力フィールドを表示する

おすすめ  (チェックしてコメントすると最新情報に掲載)
コメント :

< 前の投稿      次の投稿 >

アクセスランキング

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

  1. 2chまとめサイト - 痛いニュース(ノ∀`) (6 PV)
  2. Google Finance(グーグルファイナンス)- リアルタイム株価情報、金融ニュース、日本株 (3 PV)
  3. Google News (グーグルニュース)日本版 (3 PV)
  4. 8月15日は終戦記念日(しゅうせんきねんび、終戦の日) (2 PV)
  5. 時間指定で仲値トレードも簡単にできる無料EA「NAKANE3 Ver 2.02」 (2 PV)
  6. 裁量トレードで買い(BUY)か売り(SELL)かを判断する方法 (1 PV)
  7. 将棋ウォーズPCブラウザ版がchrome、Firefox、edgeなどに対応 (1 PV)
  8. Exness ソーシャルトレーディングの戦略プロバイダーになりました (1 PV)
  9. 東京地検、インサイダー取引の疑いで村上ファンドを捜査 (1 PV)
  10. Twitterで本の名言を共有~Inbook.jp (1 PV)

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

  1. SQLのSELECT文で先頭から上位(TOP)10件のレコードを取得する方法(SQL Server、Oracle、MySQL、PostgreSQL) (1112 PV)
  2. Google News (グーグルニュース)日本版 (240 PV)
  3. 日経平均株価(にっけいへいきんかぶか) (132 PV)
  4. 2chまとめサイト - 痛いニュース(ノ∀`) (105 PV)
  5. 安全性重視の完全無料ナンピンマーチンEA「Million Dollar(ミリオンダラー)」 #FX #ゴールド #ビットコイン (95 PV)
  6. Google Finance(グーグルファイナンス)- リアルタイム株価情報、金融ニュース、日本株 (95 PV)
  7. 仲値トレードが簡単にできる無料EA「NAKANE3 Ver 2.04」 #MT4 (90 PV)
  8. SQLiteのSELECT文で上位 (TOP) n件のデータを取得する (87 PV)
  9. 自作のMT4向け無料EA(口座縛り無し、ブローカー縛り無し、使用期限無し)とゴゴジャン出品中の有料EAの一覧 #MT4 (73 PV)
  10. 裁量トレードで買い(BUY)か売り(SELL)かを判断する方法 (71 PV)

アクセス統計

ディレクトリ

関連サイト