キッズプレート、パスタおかわり

プログラミングやデジモノについてあれこれ
--.--.-- --:--|カテゴリ:スポンサー広告| コメント(-)

スポンサーサイト


上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
2007.04.12 10:52|カテゴリ:Perlコメント(0)

Perl 正規表現中の変数展開&「e」オプションの使い方


 Perlにおいて正規表現による文字列の置換をけっこう頻繁に使用しているのですが正規表現の指定に変数を交える場合に関してのちょっとしたまとめ。

【サンプルコード】※サンプルコード中の文字コードの指定などは環境に応じて適宜編集してください以下同様
#!/usr/bin/perl
use utf8;
binmode STDOUT, ":encoding(utf8)";
binmode STDERR, ":encoding(utf8)";
binmode STDIN, ":encoding(utf8)";

#変換元のテキスト(改行交じり)
$a = "あいうえお\n".
     "かきくけこ\n".
     "さしすせそ";

#正規表現パターン
$b = "あいう";

#置換処理
$a =~ s/(${b}えお)/($1)/m;

#結果の表示
print $a . "\n";

 処理結果↓
(あいうえお)
かきくけこ
さしすせそ

 ここで疑問になるのが正規表現で文末を表す位置指定子である「$」との関係だ。ためしに置換処理の行をこうしてみた。
$a =~ s/(${b}え)$/($1)/m;

 処理結果↓
あいうえお
かきくけこ
さしすせそ

 置換されなくなった、ということは位置指定子としてちゃんと機能しているということだ。さらにこうしてみるとどうだろう?
$a =~ s/(${b}え)$か/($1)/m;

 処理結果↓
(あいうえ)お
かきくけこ
さしすせそ

「$か」が変数展開され空文字列になってしまうので、パターンにマッチしてしまう。さらにこんな指定を間違ってするという場合、期待する動作は、
「次行の先頭が“か”だった場合の行末文字を・・・」
 なんて具合の処理かもしれない。次行の先頭にある文字を指定するのに「$か」では間違いである。そのような処理を施す場合には地道にロジックを考えるか位置指定子などを使用せずに「\nか」等の指定で処理するのがベターだと思う。

 さてここまで正規表現の中での変数展開の話をしてきたが当然置換文字列の中でも変数が利用できる。

 最初に実行したソースに置換文字列用の変数「$c」を加え、さらに置換処理を以下のようにしてみた。
#置換文字列
$c = "変数展開";

#置換処理
$a =~ s/(${b}えお)$/($c)/m;

 処理結果↓
(変数展開)
かきくけこ
さしすせそ

 置換文字列中の変数がちゃんと展開されていることがわかる。

 以上の結果から正規表現文字列の中でも、置換文字列の中でも変数展開が行われることが確認できた。まあなんということはない。変数展開後の文字列で置換処理を行っていると思えば簡単だ。さてせっかく変数展開の話題に触れたのでついでに正規表現の「e」オプションについても軽く書いておこうと思う。

 正規表現の「e」オプションはこれぞPerlの真骨頂といいたくなるほど強力だ。このオプションは置換後の文字列をPerlの実行文として評価するというものだ。Perlの命令でいう「eval」に相当する。

【サンプルコード】
#!/usr/bin/perl
use utf8;
binmode STDOUT, ":encoding(utf8)";
binmode STDERR, ":encoding(utf8)";
binmode STDIN, ":encoding(utf8)";

#欧文文字列の先頭1文字を大文字にするサブルーチン
sub Top2Big {
        my @data = split(//,$_[0]);
        my $Value;
        $data[0] =~ tr/[a-z]/[A-Z]/;
        $Value = join(//,@data);
        return $Value;
}

#変換元のテキスト
$a = "hello i am hirakun";

#置換処理
$a =~ s/(\w+)/&Top2Big($1)/eg;

#結果の表示
print $a . "\n";

exit;

 処理結果↓
Hello I Am Hirakun

 どうだろう。アルファベットを全て大文字にするのであれば「tr/[a-z]/[A-Z]/」を使用すれば簡単に変換することができる。しかし、
「英単語の先頭の1文字だけを大文字にしたい」
 となると、とたんに敷居が高くなる。他のスクリプト言語であれば変換文字列の中に実行文を埋め込んであとでまとめて変数展開をかけるなどの方法をとる必要があるかもしれないが、Perlの「e」オプションを使えばマッチした文字列を引数にしてサブルーチンに飛ばし、処理結果の文字列で置換するなんてことが出来てしまう。この記述方法がいかに有用か、他の言語で同様の処理を記述してみればその強力さに気がつくと思う。
 さらにこの「e」オプションにはおもしろい特徴がある。「e」という文字を指定した数だけ評価を行うというものだ。先ほどのサンプルコードのうち「変換元テキスト」「置換処理」「結果の表示」を以下のように変更し、実行してみた。
#変換元のテキスト
$a = 'hello i am hirakun';
$b = 'hello i am hirakun';
$Syori = '&Top2Big';

#置換処理
$a =~ s/(\w+)/$Syori.'('.$1.')'/eg;
$b =~ s/(\w+)/$Syori.'('.$1.')'/eeg;

#結果の表示
print $a . "\n";
print $b . "\n";

 処理結果↓
&Top2Big(hello) &Top2Big(i) &Top2Big(am) &Top2Big(hirakun)
Hello I Am Hirakun

 結果の一行目が「e」オプションを一文字で指定したもの、二行目が「e」オプションを二文字で指定したものだ。  一度だけ指定した場合、置換文字列を実行文として評価し「変数展開と文字列の連結」が行われているのがわかる。二文字指定したものでは「変数展開と文字列の連結」が行われ、さらにその結果の文字列に対して再度評価した結果が反映されているのが見て取れる。このように「e」オプションは複数することで実行後の実行後の実行後の・・・と文字列を処理することが可能だ。  最後に一つ注意しなければいけないのだが「e」オプションは単純に変数展開をするのではなくあくまでも「実行文として評価する」オプションである。サンプルコードでも書いたように「e」オプションをつけた際には置換後の文字に()などを付加したい場合はきちんと文字列の連結子であるピリオド等を使わなければならない。さらに半角()等実行結果として表示されない文字は当然置換後の文字に含まれなくなるのでそれらの文字が含まれる文字列を操作する場合はそれなりの配慮が必要となる。
コメントの投稿












管理者にだけ表示を許可する
トラックバック
この記事のトラックバックURL

プロフィール

ひらくん Author:ひらくん
どもども、ひらんくんどす。
日々まったり過ごしております。
仕事はDTP関連のスプリクト&アプリケーション開発。
Follow happyscript on Twitter

ブログ内検索



上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。