2016/03/12
がっつり忘れていたので備忘録代わりに作成。
Perlの置換演算子 tr で半角英数字以外の文字を使う時の自分用お作法説明。
$ perl -v This is perl 5, version 20, subversion 3 (v5.20.3) built for amd64-freebsd-thread-multi Copyright 1987-2015, Larry Wall Perl may be copied only under the terms of either the Artistic License or the GNU General Public License, which may be found in the Perl 5 source kit. Complete documentation for Perl, including FAQ lists, should be found on this system using "man perl" or "perldoc perl". If you have access to the Internet, point your browser at http://www.perl.org/, the Perl Home Page. $ cat sample1.pl my $str = "12345"; $str =~ tr/12345/abcde/; print $str."\n"; $ perl sample1.pl abcde $
EUC-JPな環境でEUC-JPでスクリプトを書いていると、こんな感じでおかしくなる事がある。
変換先が日本語 | 変換元が日本語 |
---|---|
実行結果 $ perl sample2.pl あい? $ |
実行結果 $ perl sample3.pl 1211151515 $ |
スクリプトでutf-8を使う旨宣言し、スクリプト自体もutf-8エンコーディングで作成していればとりあえず動作はさせられる。
EUC-JP の環境で実行しているので nkf コマンドで utf-8 から euc-jp へ出力時の文字コードを変換している。
変換先が日本語 | 変換元が日本語 |
---|---|
実行結果 $ perl sample2utf8.pl | nkf Wide character in print at sample2utf8.pl line 7. あいうえお $ |
実行結果 $ perl sample3utf8.pl 12345 $ |
“Wide character云々”は、Perl内部形式の文字列をそのまま標準出力へ流し込もうとしたから。 後述のencode()関数を使うとこんな感じ。
use utf8; use Encode; my $str = "12345"; $str =~ tr/12345/あいうえお/; print encode('euc-jp',$str)."\n";
実行すると
$ perl sample2utf8.pl あいうえお $
Perl内部形式の文字列になっている $str をencode()関数で EUC-JP の文字列に変換している。
Perlはtr演算子の正規表現部分を実行前に確定させる。確定させるときにPerlがスクリプトの正規表現部分や文字列についてエンコーディングを知っていればそれを基にPerl内部形式への変換を行う。
先のUTF-8を使う例の use utf8; がそれだと思えばいい。同様に use eucjp; を使えればよいのだが残念ながらエラーになってしまう。
なので、evalを使って実行時に再評価させる。というかマニュアルにもeval使えと書いてあったりする。評価時に処理する正規表現や文字列がPerl内部形式であればいい。
以下のサンプルスクリプトは EUC-JP で書いてある。
変換先が日本語 | 変換元が日本語 |
---|---|
実行結果 $ perl sample5.pl あいうえお $ |
実行結果 $ perl sample6.pl 12345 $ |
Encodeモジュールは標準モジュール。Perl 5.18の時にはすでに標準。
decode()関数は指定のエンコーディングの文字列をPerl内部形式文字列に変換する。
encode()関数はPerl内部形式文字列を指定のエンコーディングの文字列に変換する。
euc-jpな環境でeuc-jpなスクリプトを書いたので、EUC-JP→内部形式/内部形式→EUC-JP の変換を decode/encode で行った。