努力したWiki

推敲の足りないメモ書き多数

ユーザ用ツール

サイト用ツール


documents:proglang:perl:perl-012

差分

このページの2つのバージョン間の差分を表示します。

この比較画面へのリンク

両方とも前のリビジョン前のリビジョン
documents:proglang:perl:perl-012 [2026/05/08 11:54] – ↷ documents:perl:perl-012 から documents:proglang:perl:perl-012 へページを移動しました。 k896951documents:proglang:perl:perl-012 [2026/05/17 14:59] (現在) – [置換演算子 tr/// で日本語文字へ置換するor日本語文字を置換する] k896951
行 1: 行 1:
 +====== 002.置換演算子 tr/// で日本語文字へ置換するor日本語文字を置換する ======
  
 +2016/03/12\\
 +がっつり忘れていたので備忘録代わりに作成。
 +
 +===== 概要 =====
 +
 +Perlの置換演算子 tr で半角英数字以外の文字を使う時の自分用お作法説明。
 +
 +===== Perl環境とベースコード =====
 +
 +<code>
 +$ 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
 +$
 +</code>
 +
 +===== 日本語文字が含まれる場合の対処 =====
 +
 +==== 含まれる例 ====
 +
 +EUC-JPな環境でEUC-JPでスクリプトを書いていると、こんな感じでおかしくなる事がある。
 +
 +^ 変換先が日本語 ^ 変換元が日本語 ^
 +|<code perl sample2.pl>
 +my $str = "12345";
 +
 +$str =~ tr/12345/あいうえお/;
 +
 +print $str."\n";
 +</code>実行結果<code>
 +$ perl sample2.pl
 +あい?
 +$
 +</code> | <code perl sample3.pl>
 +my $str = "あいうえお";
 +
 +$str =~ tr/あいうえお/12345/;
 +
 +print $str."\n";
 +</code> 実行結果 <code>
 +$ perl sample3.pl
 +1211151515
 +$
 +</code> |
 +
 +==== UTF-8でスクリプトを作成する ====
 +
 +スクリプトでutf-8を使う旨宣言し、スクリプト自体もutf-8エンコーディングで作成していればとりあえず動作はさせられる。\\
 +EUC-JP の環境で実行しているので nkf コマンドで utf-8 から euc-jp へ出力時の文字コードを変換している。
 +
 +^ 変換先が日本語 ^ 変換元が日本語 ^
 +|<code perl sample2utf8.pl>
 +use utf8;
 +
 +my $str = "12345";
 +
 +$str =~ tr/12345/あいうえお/;
 +
 +print $str."\n";
 +</code>実行結果<code>
 +$ perl sample2utf8.pl | nkf
 +Wide character in print at sample2utf8.pl line 7.
 +あいうえお
 +$
 +</code> | <code perl sample3utf8.pl>
 +use utf8;
 +
 +my $str = "あいうえお";
 +
 +$str =~ tr/あいうえお/12345/;
 +
 +print $str."\n";
 +</code> 実行結果 <code>
 +$ perl sample3utf8.pl
 +12345
 +$
 +</code> |
 +
 +"Wide character云々"は、Perl内部形式の文字列をそのまま標準出力へ流し込もうとしたから。
 +後述のencode()関数を使うとこんな感じ。
 +<code perl>
 +use utf8;
 +use Encode;
 +
 +my $str = "12345";
 +
 +$str =~ tr/12345/あいうえお/;
 +
 +print encode('euc-jp',$str)."\n";
 +</code>
 +実行すると
 +<code>
 +$ perl sample2utf8.pl
 +あいうえお
 +
 +</code>
 +Perl内部形式の文字列になっている $str をencode()関数で EUC-JP の文字列に変換している。
 +
 +==== evalとEncode.pmで内部形式に変換 ====
 +
 +Perlはtr演算子の正規表現部分を実行前に確定させる。確定させるときにPerlがスクリプトの正規表現部分や文字列についてエンコーディングを知っていればそれを基にPerl内部形式への変換を行う。\\
 +先のUTF-8を使う例の use utf8; がそれだと思えばいい。同様に use eucjp; を使えればよいのだが残念ながらエラーになってしまう。
 +
 +なので、evalを使って実行時に再評価させる。というかマニュアルにもeval使えと書いてあったりする。評価時に処理する正規表現や文字列がPerl内部形式であればいい。
 +
 +以下のサンプルスクリプトは EUC-JP で書いてある。
 +
 +^ 変換先が日本語 ^ 変換元が日本語 ^
 +|<code perl sample5.pl>
 +use Encode;
 +
 +my $str  = decode('euc-jp',"12345");
 +my $from = decode('euc-jp',"12345");
 +my $to   = decode('euc-jp',"あいうえお");
 +
 +# eval "\$str =~ tr/\$from/\$to/"; じゃ駄目だよ
 +eval "\$str =~ tr/$from/$to/";
 +
 +print encode('euc-jp',$str)."\n";
 +</code>実行結果<code>
 +$ perl sample5.pl
 +あいうえお
 +$
 +</code> | <code perl sample6.pl>
 +use Encode;
 +
 +my $str  = decode('euc-jp',"あいうえお");
 +my $from = decode('euc-jp',"あいうえお");
 +my $to   = decode('euc-jp',"12345");
 +
 +# eval "\$str =~ tr/\$from/\$to/"; じゃ駄目だよ
 +eval "\$str =~ tr/$from/$to/";
 +
 +print encode('euc-jp',$str)."\n";
 +</code> 実行結果 <code>
 +$ perl sample6.pl
 +12345
 +$
 +</code> |
 +
 +Encodeモジュールは標準モジュール。Perl 5.18の時にはすでに標準。
 +
 +decode()関数は指定のエンコーディングの文字列をPerl内部形式文字列に変換する。\\
 +encode()関数はPerl内部形式文字列を指定のエンコーディングの文字列に変換する。
 +
 +euc-jpな環境でeuc-jpなスクリプトを書いたので、EUC-JP→内部形式/内部形式→EUC-JP の変換を decode/encode で行った。
 +
 +
 +{{tag>技術資料 Perl tr 置換演算子}}
documents/proglang/perl/perl-012.txt · 最終更新: by k896951

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki