職場実習3日目

引き続きperlプログラミング。
CGI-Perl 基礎編 (その八) 正規表現、マッチパターン、置換演算子、変換演算子 - SAK Streets

全角数字と半角数字の変換(文字コードの扱い)

最初は正規表現を使った変換を考えたが、文字化けしてしまいうまくいかず。

$line = '0123456789';
$line =~ tr/[0-9]/[0-9]/;

一文字ごとに切り分け、ハッシュで変換した後、再連結する方法を思いついたが、思った通りに変換されず、半角数字が習得できない。

# ハッシュ(全角数字 => 半角数字)
%hash_zen2han_number = (
    '0' => '0', '1' => '1', '2' => '2', '3' => '3', '4' => '4', 
    '5' => '5', '6' => '6', '7' => '7', '8' => '8', '9' => '9'
);
# サブルーチン(全角数字列 => 半角数字列)
sub zen2han_numbr {
    (my $zstr) = @_;
    my @zchrarray = split(//, $zstr); # 文字ごとに切り分ける
    my $hstr = '';
    my $hch = '';
    foreach my $zch (@zchrarray) {
        $hch = $hash_zen2han_number{$zch}; # 全角->半角変換
        $hstr .= $hch; # 文字連結
    }
}

ハッシュで1文字のみの変換を試したところ、うまく変換できたので、再連結する箇所で、間に「|」記号を入れてみたところ、全角文字が正しく切り分けられておらず、文字化けした記号と「|」が交互に並んだ文字列が出てきた。
ソースの文字コードUTF-8だが、Shift-JIS同様、多バイト文字は1バイト単位で切り分けられている模様。
その後、試行錯誤を経て、以下のサイトを見つけた。
Perl 5.8でUTF-8の文字コードを扱う
Perl 5.8.x における日本語コード変換のメモ
自分が使っているperlのバージョンは5.8.8であり、use utf8;を宣言することで内部的にUTF-8で処理されるらしい。これによって、多バイト文字も内部的に1バイト文字同様、1文字として扱われるようになる。
この方法で再び試した結果、うまく変換された。

置換文字列の変数による記述

文字列置換でマッチングパターンと置換文字列をそれぞれリテラルではなく変数で記述しようとしたが、うまくいかない。

$pattern_matching = "開始(.*?)終了"; # マッチングパターン
$pattern_result = "$1"; # 置換文字列パターン
$text = "ABCDE開始12345終了ABCDE"; # 置換する文字列
$text =~ s/$pattern_matching/$pattern_result/g; # 文字列置換

このようにすると、置換文字列中の変数名が文字列代入時に展開されてしまうため、置換結果が「ABCDEABCDE」となる。($1の内容が空の場合)
「$pattern_result = '$1';」に変えた場合、置換時に変数展開されず、「ABCDE$1ABCDE」になる。
$pattern_matching中の(.*?)にマッチした部分を$1の変数展開で挿入したいので、その方法を探したところ、以下のサイトが見つかった。
キッズプレート、パスタおかわり Perl 正規表現中の変数展開&「e」オプションの使い方〜ひらくんとスパイダ−キングダム
置換時に変数展開するためには、置換文字列を式に見立てて、評価する必要がある。そこで置換文字列ごとシングルクォート('')で囲んで、2回評価すればいい事が分かった。

$pattern_matching = "開始(.*?)終了"; # マッチングパターン
$pattern_result = '"$1"'; # 置換文字列パターン
$text = "ABCDE開始12345終了ABCDE"; # 置換する文字列
$text =~ s/$pattern_matching/$pattern_result/eeg; # 文字列置換(2回評価)

1回目の評価で外側のシングルクォートを外し、2回目の評価で内側のダブルクォートを外し、以下の処理と同じことを行う。

$text =~ s/開始(.*?)終了/$1/g;

これで、前もって用意した変数で文字列置換を行う事ができる。

perlで文字データの処理は終わったが…

読み込んだ組版データを加工してファイルに出力する処理を何とか完成させたが、出力データが完全ではなかったらしい。組版データとして読み込んで画面に正しく表示するためには、別の定義ファイルも必要との事。まだまだperlの課題は続きそう。