perlにおいて半角英数字を全角英数字へ変換するには?

[上に] [前に] [次に]
riko 2000/03/31(金) 00:15:39
perlにおいて半角英数字を全角英数字へ変換するにはどうしたらよいのでしょうか?
某雑誌では、次のスクリプトを使うようなことが書いてありましたが、機能してくれません。
&jcode'tr(*value,'0-9A-Za-z','0-9A-Za-z');

tanaka 2000/03/31(金) 03:55:26
全角の所で、0−9A−Za−zの三箇所の「−」は、半角の
マイナスで、記述すれば、動作すると思います。
半角で記述されてましたら、すいません。わかりません。

riko 2000/04/01(土) 01:14:19
半角ですが、だめです。
何方かアドバイス頂けないでしょうか。

ふじ 2000/04/01(土) 01:19:02
require 'jcode.pl';

てしてますよね?念のため。

あと、スレッドが有効になっている Perl では jcode.pl 2.10
以前のものは使用できないので、2.10 以前のを使っているなら
2.11 を使用しましょう。

ftp://ftp.iij.ad.jp/pub/IIJ/dist/utashiro/perl/

jcode.pl 2000/04/01(土) 10:24:00
sabre氏のjcode.pl の私的な解説書
http://ina.kappe.co.jp/~sabre/kcode/jcode.html

mm 2000/04/01(土) 13:44:31
>http://ina.kappe.co.jp/~sabre/kcode/jcode.html
trの説明の項に間違いがあります。
>$line のエンコード及びスクリプト自身は、JIS か EUC でなければなりません。
シフトJISでも使えます。ただ、- による範囲指定が出来ないだけです。
(以前にも書いたんですが、検索が使えないそうなので…)

質問者の方の使用文字コードはなんでしょうか?

jcode.pl 2000/04/02(日) 00:14:50
>シフトJISでも使えます。
jcode.pl (v2.6)のファイル内にもそうあったので,
EUCだと思っていましたが,そうだったのですか.
それは面白いことを教えていただきました.

&jcode'tr(*line, $from, $to [, $option]);
&jcode'tr emulates tr operator for 2 byte code.
Only 'd' is interpreted as option.
Range operator like `A-Z' for 2 byte code is partially supported.
Code must be JIS or EUC, and first byte should be same on first and last character.

mm 2000/04/02(日) 00:40:34
>http://ina.kappe.co.jp/~sabre/kcode/jcode.html
にメールしておこうと思って、ちょっと調べてみたら、いろいろ出て来ました。

シフトJISでも tr は使えると書きましたが、ソースを見ると、半角カナは使えませんでした。

jcode.plの履歴によれば、以下の問題もあるようです。
>昨年末にリリースした jcode.pl-2.9 にバグがあることを発見しました。コー
>ド変換には支障がありませんが、&jcode'tr がうまく動作しません。


jcode.pl さん
>Code must be JIS or EUC, and first byte should be same on first and last character.
上のメールに書いた内容を引用しておきます。
−−−以下引用
jcode.plのソースの sub tr の実装で、1文字ごとへの分解を
行う部分でも、

    $s =~ s/([\200-\377][\000-\377]|[\000-\377])/

とあるように、日本語の第2バイトは、[\000-\377]で指定して、
EUCだけでなくシフトJISも考慮したものとなっています。
(ただし、いわゆる半角カナは使えませんが)

また、jcode.pl のソースの &jcode'tr の解説中にある↓で

;# Range operator like `A-Z' for 2 byte code is partially
;# supported.  Code must be JIS or EUC, and first byte
;# have to be same on first and last character.

文字コードをJISとEUCだけに制限してるのは、
私も当初誤解したのですが、Range operator、即ち A-Z のように
- を使って範囲を指定する場合に限っての制限だと思います。
実際、ソースコード中の - の展開部分では、

    grep(s/(([\200-\377])[\200-\377]-\2[\200-\377])/&_expnd2($1)/ge,

とあるように、日本語の第2バイトは、[\200-\377]で指定しているので、
EUCにしか対応していません。

従って、文字コードがシフトJISの場合であっても、
- による範囲指定を使わずに、'ABCDEFGHI…' というように
全ての文字を指定して使用すれば、&tr の利用は可能です。
(ただし、いわゆる半角カナは除く)
−−−引用以上


とにかく、質問者の方の使用環境や、具体的にどのように機能しないのかが
分からないことには、問題も解決しないと思います。

riko 2000/04/02(日) 02:58:58
皆様、色々アドバイスありがとうございます。
jcode.pl,のバージョンを1.9から2.11したら多少改善しましたが、
まだバグってます。

入力した数字      全角変換後の値
 123456789  →  −9A−Zabcd

参考:次のローカル環境で実施しております。
HTTP Daemon version1.12
Perl for Win32(perl5) Base Build 316
jcode.pl,v 2.11


スクリプトの内容

#!/usr/local/bin/perl

require 'jcode.pl';
$datafile = './data.txt';

if ($ENV{'SERVER_SOFTWARE'} =~ /^AnWeb/) {$flock ='';}

$buffer = $ENV{'QUERY_STRING'};
@pairs = split(/&/,$buffer);
foreach $pair (@pairs)
{
($name, $value) = split(/=/, $pair);
$value =~ tr/+/ /;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;

&jcode'tr(*value,'0-9A-Za-z','0-9A-Za-z');
&jcode'tr(*value,'.,:/@?#&-','.,:/@?#&−');

$FORM{$name} = $value;
}

$figure = $FORM{'figure'};
&jcode'convert(*figure,'sjis');

print "$figure\n";
exit;

mm 2000/04/02(日) 04:10:52
>Perl for Win32(perl5) Base Build 316
> 123456789  →  −9A−Zabcd

やはりShift-JISで tr に - を使った場合の問題のようですね。
A-Zは第2バイトが \200 未満なので展開されないが、
a-zは第2バイトが \200 以上なので展開されて、そのようになります。


&jcode'convert(*value,'euc');
として、事前に文字コードをEUCに変更しておくか、

>&jcode'tr(*value,'0-9A-Za-z','0-9A-Za-z');

の第3引数を↓のように - を使わない書き方に替えて下さい。

&jcode'tr(*value,'0-9A-Za-z','0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz');

・半角文字には - が使えるので、第2引数はそのままでも大丈夫です。
・第3引数の abcdef… z は、上の理由により a-z でもいいのですが、
 ややこしくなるので、これも↑のように展開した方がいいでしょう。

riko 2000/04/03(月) 00:19:28
[[解決]]
ありがとうございます。
無事解決致しました。

mm 2000/04/03(月) 23:24:08
解決したので、追伸ですが、
http://ina.kappe.co.jp/~sabre/kcode/jcode.html
の管理者の方から、シフトJISでも使えることの確認と、
近日に書き換える旨の返事を頂きました。

[上に] [前に] [次に]