JavaScript で Windows 機種依存文字を置換するスクリプト
仕事で Windows の機種依存文字を代替文字へ置換するスクリプトを書くことになりました。
そんなの書くの面倒くさいのでとりあえずググって見たんだけど、イマイチこれが見つかりません。文字コードの変換じゃぁなくて代替文字への置換なんて要求はそもそも皆無に等しいのか・・・と感じてしまったけど、まぁいいや。
しかも本当は Perl 側でやりたかったんだけど、正規表現でパパッとやってしまおうとしたら、余計なところまでマッチングされてしまって、どうにもうまくいかない・・・。真面目に1byteずつ比較するしかないの?これ?
あぁ・・・よく考えたら perl のスクリプトを euc で書いてたからだ。今 utf8 で保存し直したら上手くいったわ。
まぁ考えるのも面倒くさかったので JavaScript で実装してブラウザ側で処理させちゃうことにしました。JavaScript は内部処理が unicode なので何も考えずに(しかも手抜きで)実装したら正確にマッチングしてくれた。mac os を考慮すると機種依存文字はぐぐっと増えるのですが、手抜きなので mac os の事はひとまず忘れておきます。とりあえず置換対象は下記の文字たち。
まずはココに機種依存文字を入力してみます。デフォルトで置換対象を入れておいたけど、mac os では文字化けしてるんだろうなぁ・・・(^^ゞ
置換スクリプトのソースはこんな感じ。処理効率とか考えていない手抜き実装ですが、何かの役には立つかも。
// 機種依存文字置換関数 function replace_Char(textid){ var text = textid.value; var ngchr = [ '?','?','?','?','?','?','?','?','?','?','?','?','?','?','?', '?','?','?','?','?','?','?','?','?','?','?','?','?','?','?', '?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?', '?','?','?','?','?','?','?','?', '?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?', ]; var trnchr = [ '(1)','(2)','(3)','(4)','(5)','(6)','(7)','(8)','(9)','(10)','(11)','(12)','(13)','(14)','(15)', '(16)','(17)','(18)','(19)','(20)','I','II','III','IV','V','VI','VII','VIII','IX','X', 'ミリ','キロ','センチ','メートル','グラム','トン','アール','ヘクタール','リットル','ワット','カロリー','ドル','セント','パーセント','ミリバール','ページ', 'mm','cm','km','mg','kg','cc','平方メートル','平成', '「','」','No.','K.K.','TEL','(上)','(中)','(下)','(左)','(右)','(株)','(有)','(代)','明治','大正','昭和', ]; for(var i=0; i<=ngchr.length;i++){ text = text.replace( ngchr[i], trnchr[i], 'mg' ); } textid.value = text; } // 機種依存文字チェック関数 function chk_Char(textid){ var text = textid.value; var c_regP = "[??????????????????????????????????????????????????????????????????????]"; var c_errMsg = ''; if(text.match(c_regP)){ c_errMsg = '機種依存文字が使われています。自動置換しますか?'; } if(c_errMsg){ if(confirm(c_errMsg)){ replace_Char(textid); textid.value = textid.value.replace(/[\r|\n]/mg, ''); return false; } return false; }; return true; }
ちなみに perl のテストプログラムはこんな感じに書いて windows のコマンドラインでテストしていました。utf8 で保存すれば正常に動きます。未だに Jcode 使ってるのかよって突っ込みはナシで・・・(^^ゞ
use Jcode; my $text = qq{ 'キロ?', }; my @ngchr = ( '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', ); my @trnchr = ( '(1)','(2)','(3)','(4)','(5)','(6)','(7)','(8)','(9)','(10)', '(11)','(12)','(13)','(14)','(15)','(16)','(17)','(18)','(19)','(20)', 'I','II','III','IV','V','VI','VII','VIII','IX','X', 'ミリ','キロ','センチ','メートル','グラム','トン','アール','ヘクタール','リットル','ワット', 'カロリー','ドル','セント','パーセント','ミリバール','ページ','mm','cm','km','mg', 'kg','cc','平方メートル','平成','「','」','No.','K.K.','TEL','(上)', '(中)','(下)','(左)','(右)','(株)','(有)','(代)','明治','大正','昭和', ); print Jcode->new($text)->sjis; for ( my $i = 0 ; $i < scalar @ngchr ; $i++ ) { $text =~ s/$ngchr[$i]/$trnchr[$i]/mg; } print Jcode->new($text)->sjis;
コメントやシェアをお願いします!
ありりん
お返事もらえたーヽ(´ー`)ノ
>あのツール関連
今ならもうちょっと良く書けそうではありますけど、はてさて・・・。
それより、アレまだ使ってたんですか。
それなりにちゃんと作ったから実用に耐えておるならば、そりゃ嬉しいですけど。
それでも老婆心ながら、.Net化した方がいいのではと思ってしまいました。
コードを分析するのではなく、仕様を継いだ形なら開発者見つかるのでは?
長文すいません。。。
drk
>otsuneさん
コメント有り難うございます。Unicode::Normalize ですか。恥ずかしながら初めて知りました。参考にさせていただきます。
>ありりんさん
お仕事とは、例によってあのツール関連です〜(苦笑
otsune
>置換対象は下記の文字たち。
そのへんは Unicode::Normalize をパクってjsで書き直せばいいんじゃないかなぁ。と思いました。
ありりん
>機種依存文字を代替文字へ置換する
いろんなところで、似たようなの書いてます。。
ニーズはあるんですけどフリーにしかならなかったり、要求が表面化する前に
実装してたりそんな感じで、あまりWeb上にはないかもですね。
文字コードが並んでるので、記事のような配列で持っていってもいいですし、
連想配列にしてもいいとも思いますけど、キーに設定できるのかPerlの仕様忘れました(;´ρ`)
あと、カナ英字空白の全角半角、かなカナ変換なんかありますけど、
作っても便利だと思うんですけど、使用者は「当然」と思うだけなんですよね。なーむ。
ではは。