アプリ版:「スタンプのみでお礼する」機能のリリースについて

jcode.plの
jcode::tr()
のかわりを探しています。

jcode.plの
jcode::tr(\$val,'0-9A-Za-z ()_@-','0-9A-Za-z ()_@-');
をPerl5.18.2で使用するとエラーが出てしまいます。これを回避したい。

プログラムがUTF-8であれば
$val =~ tr/0-9A-Za-z ()_@-/0-9A-Za-z ()_@-/;
のようにすれば実現可能みたいですが、プログラムはEUCで書かれています。
影響範囲からプログラムの文字コードをかえることはできれば避けたい。

一文字ずつ変換することも考えましたが、この方法ではパフォーマンスに懸念があります。

jacode.plなるものもありますが、これに置き換えるだけでは文字化けしてしまいました。

jcode::tr()のかわりになるような手段はあるのでしょうか?

A 回答 (7件)

UTF-8 の内部文字列にすれば、tr で文字単位で変換することができます。

プログラムのソースが EUC-JP でとのことなので、少し厄介なところはあります。

use strict;
use Encode;
use NKF;

my $str = "\xAD\xEA0101アア";
$str = decode 'utf8', nkf('-Ew', $str);
my $from = decode 'utf8', nkf('-Ew', '0-9A-Za-z ()_@ー');
eval "\$str =~ tr/$from/0-9A-Za-z ()_\@-/;";
$str = nkf '-We', encode('utf8', $str);
print "$str\n";

私の Linux 上のパソコンでは、上記のコードで (株) は文字化けせずに全角の0と1を半角に変換します。
    • good
    • 0
この回答へのお礼

ありがとうございます。
無事変換できました。

意図してない半角カナまで全角になってますが、
それも必要なことなので問題ありませんでした。

お礼日時:2014/03/12 15:56

(株) のような特殊な文字では、Jcode から利用している Encode.pm でもうまく行かないことがあります。

(株) の場合は、「euc-jp → utf8」は変換できるが、「utf8 → euc-jp」は変換できないようです (No4 の補足に書かれているとおりです)。

use Encode;
print encode('utf8', decode('euc-jp', "\xAD\xEA")), "\n"; # 端末UTF-8: OK
print encode('euc-jp', decode('utf8', "\xE3\x88\xB1")), "\n"; # 端末euc-jp: NG

日本語変換ユーティリティ nkf が NKF.pm を提供しています。Encode.pm で「UTF-8バイト <-> UTF-8内部」を、NKF.pm で「UTF-8バイト <-> EUC-JP」を処理すると、うまく行くかも?

この回答への補足

文字を
EUC→UTF-8→EUC
にするだけなら
Unicode::Japanese
を使えば可能でした。

問題は任意の文字を変換することです。
0-9a-z

0-9a-z
のように半角にするとか。全角文字を全部半角にすることは出来るんですが
上記のように英数字だけとかが出来ないんです。

補足日時:2014/03/12 14:29
    • good
    • 0

「文字化け」とかいう曖昧な情報では埒があきません。


odを使って、どんなデータになっているか調べましょう

#1にあったスクリプトを
LANG=C od -t x1c スクリプト
と16進と文字とで表示します。
非ASCII文字を表示させないために、LANG=Cにしておきます。
次のように表示されるかと思います。
0000000 75 73 65 20 4a 63 6f 64 65 3b 0a 0a 6d 79 20 24
      u s e J c o d e ; \n \n m y $
0000020 73 74 72 20 3d 20 22 28 b3 f4 29 a3 b0 a3 b1 30
      s t r = " ( 263 364 ) 243 260 243 261 0
# ここの特性上、位置がずれてしまいます
EUC-JPで書いてあれば、「株」にあたるコードは b3 f4 になっているはずです。
8a 94 ならShift JIS, e6 a0 aa ならUTF-8です。


次に、実行結果のダンプを取ります
perl スクリプト | LANG=C od -t x1c
本来なら、 ここでも b3 f4 になっているはずです。
もし b3 f4 ならば、使っている端末アプリケーションが文字化けの原因です。(LANGはeucJPになっているけど、端末の文字コード設定が別なものになっている、とか)
もし、それ以外のコードになっているなら、JCodeでの変換がなにかうまくいっていない、ということになります。

この回答への補足

いろいろ考えていただきありがとうございます。

1つお詫びです。
普通の感じの「株」でなく「(株)」のような機種依存文字が化けます。

教えて頂いた方法でいろいろ試してみました。

まず「株」で
何も変換せずダンプ
b3 f4 0a
UTF-8に変換
e6 a0 aa 0a
UTF-8に変換後、EUCに変換
b3 f4 0a

元に戻っているのでロジックや確認方法は正しく行えていると思います。
次に「(株)」
何も変換せずダンプ
ad ea 0a
UTF-8に変換
e3 88 b1 0a
UTF-8に変換後、EUCに変換
3f 0a

こっちは元に戻りませんでした。
やはりJcodeの文字コード変換では対応出来ていない部分があるようです。

補足日時:2014/03/12 14:15
    • good
    • 0

文字コードの指定には、"jis"、"sjis"、 "euc"、"ucs2"、"utf8"が使えます。



my $str = "(株)0101アア";
$codes = Jcode::getcode();
$str = Jcode->new( $str, 'euc')->utf8;

このutf8変換後の$codesと$strの文字列内容を教えていただけませんか。
ucs2ではないかと思うので、こうするとどうでしょうか。

my $str = "(株)0101アア";
$codes = Jcode::getcode();
$str = Jcode->new( $str, 'ucs2')->utf8;

この回答への補足

$codesには
ascii
が入ってました。

$str = Jcode->new( $str, 'euc')->utf8;
で実行した結果、コンソールの表示文字列をUTF8にしたら化けてなかったので
UTF8には変換出来ているようです。

この状態で
$str = Jcode->new( $str, 'utf8')->euc;
を実行すると株が化けます。
JcodeではUTF-8からEUCに変換できない文字があるんですかね?

補足日時:2014/03/11 11:44
    • good
    • 0

私の手許の環境では文字化けしません。


UTF-8の端末で実行していたり、スクリプトがEUC-JPではなかったりしませんか?

この回答への補足

Solaris10でLANGはja_JP.eucJPになってるんですけどねぇ。
スクリプトもEUCになってますし。

普通の文字は文字化けしませんが、カッコ株のような特殊な文字がダメです。

補足日時:2014/03/11 10:14
    • good
    • 0

文字列をUTF-8に変換してから文字列操作するのが基本ですよ。

この回答への補足

カッコ株はEUC→UTF-8→EUCにするだけでも文字化けしてしまいます。

----------------------------------
use Jcode;

my $str = "(株)0101アア";

$str = Jcode->new( $str, 'euc')->utf8;
$str = Jcode->new( $str, 'utf8')->euc;

print $str."\n";
----------------------------------
これはまた別問題ですが・・・・

補足日時:2014/03/11 10:12
    • good
    • 0

Jcode.pm などはどうでしょうか。


Jcode呼び出しの"J"は大文字になります。

http://openlab.jp/Jcode/index-j.html

この回答への補足

ご回答ありがとうございます。

use Jcode;

my $str = "(株)0101アア";

my $j = Jcode->new($str, 'euc');

$str= $j->tr('0-9A-Za-z ()_@-','0-9A-Za-z ()_@-');

print $str."\n";

こんな感じで実行すると、全角数字を半角に変換は出来ましたが
(株)が文字化けしてしまいまいした。

補足日時:2014/03/10 16:17
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!