18 December 2010

(Perl) 波ダッシュ(〜)を全角チルダ(~)に変換する

MacOSやLinuxで入力した 「〜」 (波ダッシュ wave dash)は、Windowsでは文字化けしたり、汚いフォントで表示されるようだ。

Unicode標準化で日本人の”協力度合い”が低かったので、日本語のフォントがなおざりにされた結果だとか…

Wikipedia の『波ダッシュ』記事に詳しく書かれている。

さて、ガラパゴス言語である日本語に対応させるため、LinuxやMacで入力したテキストを、Windows対応する必要がある場合もある。その時に、世界標準の「波ダッシュ」を「全角チルダ」に変換するスクリプト(赤色に着色したところ)

任意のエンコード形式から、任意のエンコード形式へ変換する機能も付けといた (緑色に着色したところ)

#!/usr/bin/perl use warnings; use strict; use utf8; use Encode::Guess qw/euc-jp shiftjis iso-2022-jp/; my $output_encode = 'utf8'; # 出力時のエンコード my $flag_conv_wavedash = 0; # 波ダッシュ(U+301C)を全角チルダ(U+FF5E)に変換 print("\nfile encode changer\n\n"); # ファイル名のユーザ入力 print 'input filename : '; $_ = <STDIN>; chomp; unless(-f $_){ die "pogram aborted : file not found ($_)\n"; } # ファイルから、改行を無視して、一気に読み込む open(FH, "<$_") or die("program aborted : file open error ($_)\n"); my $strAllLines = undef; { local $/ = undef; # 改行を区切りとして使わない $strAllLines = <FH>; } close(FH); my $input_encode = ''; my $enc = Encode::Guess->guess($strAllLines); if(ref($enc) eq 'Encode::utf8'){ $input_encode = 'utf8'; } elsif(ref($enc) eq 'Encode::Unicode'){ $input_encode = $$enc{'Name'}; } elsif(ref($enc) eq 'Encode::XS'){ $input_encode = $enc->mime_name(); } elsif(ref($enc) eq 'Encode::JP::JIS7'){ $input_encode = $$enc{'Name'}; } else{ # 二つ以上のエンコードが推定される場合は、$encに文字列が返る die("program aborted : unknown encode (".$enc.")\n"); } print("input file encode is $input_encode\n\n"); # 変換先のエンコード形式をユーザ入力 printf("Select output encode\n 1.utf8\n 2.shiftjis (cp932)\n 3.iso-2022-jp (jis)\n". " 4.euc-jp\n 5.utf-16\n 6.utf-32\n 1/2/3/4/5/6 ? : "); $_ = <STDIN>; chomp; if(length($_)<=0){ die("select error\n"); } elsif(uc($_) eq '1'){ $output_encode = 'utf8'; } elsif(uc($_) eq '2'){ $output_encode = 'shiftjis'; } elsif(uc($_) eq '3'){ $output_encode = 'iso-2022-jp'; } elsif(uc($_) eq '4'){ $output_encode = 'euc-jp'; } elsif(uc($_) eq '5'){ $output_encode = 'UTF-16'; } elsif(uc($_) eq '6'){ $output_encode = 'UTF-32'; } else { die("program aborted : selection is not correct\n"); } # 波ダッシュ(〜)変換モードの決定 print("convert japanese 'wave dash' to 'full width tilde' for Windows compatible (Y/N) [N] : "); $_ = <STDIN>; chomp(); if(uc($_) eq 'Y'){ $flag_conv_wavedash = 1; } elsif(uc($_) eq 'N' || length($_)<=0){ $flag_conv_wavedash = 0; } else{ die("program aborted : invalid imput\n"); } # 出力ファイルのユーザ入力 print 'output filename : '; $_ = <STDIN>; chomp; if(-e $_ && !(-w $_)){ die "program aborted : file is not writable ($_)\n"; } print("converting ($input_encode -> $output_encode) ...\n"); # ファイルに書き込む open(FH, ">$_") or die("program aborted : file open error ($_)\n"); $strAllLines = $enc->decode($strAllLines); # input encode → utf8 # 波ダッシュ変換 301C→FF5E my $ch_wavedash = pack('U',0x301c); my $ch_fullwidthtilde = pack('U',0xff5e); if($flag_conv_wavedash == 1){ $strAllLines =~ s/$ch_wavedash/$ch_fullwidthtilde/g; } print(FH Encode::encode($output_encode, $strAllLines)); # utf8 → output encode close(FH); print("conversion succeed !\n");