半角カナ全角変換(濁点、半濁点付き対応)

半角カタカナを全角のカタカナに変換します。構文チェックの前処理などに有効です。
半濁点、濁点が付きで2文字で構成される文字も、全角1文字に変換してしまいます。
この HTML 上では漢字がシフトJIS になっていますが、本来は EUC 専用となっています。


# 半角カナ文字を全角に変換する(EUC 専用)
sub hkana2zkana
{
    my(@hkana2zkana_tbl) = (
        # 0xa0 - 0xdf の文字コード相当
        " ", "。", "「", "」", "、", "・", "ヲ", "ァ",  # a0-
        "ィ", "ゥ", "ェ", "ォ", "ャ", "ュ", "ョ", "ッ",  # a8-
        "ー", "ア", "イ", "ウ", "エ", "オ", "カ", "キ",  # b0-
        "ク", "ケ", "コ", "サ", "シ", "ス", "セ", "ソ",  # b8-
        "タ", "チ", "ツ", "テ", "ト", "ナ", "ニ", "ヌ",  # c0-
        "ネ", "ノ", "ハ", "ヒ", "フ", "ヘ", "ホ", "マ",  # c8-
        "ミ", "ム", "メ", "モ", "ヤ", "ユ", "ヨ", "ラ",  # d0-
        "リ", "ル", "レ", "ロ", "ワ", "ン", "゛", "゜"   # d8-
    );
    my(@hkana2zkana_tbl_daku) = (
        # 濁点変換
        "x",  "x",  "x",  "x",  "x",  "x",  "ガ", "ギ",  # b0-
        "グ", "ゲ", "ゴ", "ザ", "ジ", "ズ", "ゼ", "ゾ",  # b8-
        "ダ", "ヂ", "ヅ", "デ", "ド", "x",  "x",  "x",   # c0-
        "x",  "x",  "バ", "ビ", "ブ", "ベ", "ボ", "x"    # c8-
    );
    my(@hkana2zkana_tbl_han) = (
        # 半濁点変換
        "x",  "x",  "パ", "ピ", "プ", "ペ", "ポ", "x"    # c8-
    );

    my($wk) = $_[0];
    my($lm1) = length($wk);
    
    for (my($i) = 0 ; $i < $lm1 ; ) {
        my($one) = ord(substr($wk, $i, 1));
        if ( $one >= 128 ) {
            # 2 byte code
            if ( $one == 0x8e ) {
                # 半角カナ文字マーク
                my($two) = ord(substr($wk, $i+1, 1));
                if ($two >= 0xa0 && $two <= 0xdf) {
                    # 半角カナを全角に変換
                    my($next) = substr($wk, $i+2, 2);
                    if ($next eq "゛" && $two >= 0xb0 && $two <= 0xcf && $hkana2zkana_tbl_daku[$two-0xb0] ne "x") {
                        # 濁点合成 
                        substr($wk, $i, 4) = $hkana2zkana_tbl_daku[$two-0xb0];
                        $lm1 -= 2;     # 長さが変わったので修正
                    } elsif ($next eq "゜" && $two >= 0xc8 && $two <= 0xcf && $hkana2zkana_tbl_han[$two-0xc8] ne "x") {
                        # 半濁点合成
                        substr($wk, $i, 4) = $hkana2zkana_tbl_han[$two-0xc8];
                        $lm1 -= 2;     # 長さが変わったので修正
                    } else {
                        substr($wk, $i, 2) = $hkana2zkana_tbl[$two-0xa0];
                    }
                } else {
                    # 不正?なので空白に変換
                    substr($wk, $i, 2) = "  ";
                }
            }
            $i+=2;
        } else {
            # 1 byte code
            $i++;
        }
    }
    
    return ($wk);
}

総合ホームページ Perl納戸部屋