Perlの思い出し書き
初心者の頃、探すのに困ったことや、わからなかったことなど。思い出したらメモっていきます。
q(), qq()
q()はシングルクオート。qq()はダブルクオート。つまり、''や""と同じ意味。
print "ダブルクオート \"\"\n"; print qq(ダブルクオート ""\n);
qw//, qw()
qwは、空白で区切られた文字列をリストにする。
@str = qw(hoge hage hige huga); @str = ("hoge", "hage", "hige", "huga");
qqや正規表現などでも、()の変わりに//や||や??、!!など色々な記号が使える。
use CGI qw/:cgi :form/; # 同じ use CGI qw!:cgi :form!; # 同じ use CGI qw(:cgi :form); # 同じ
これって、初心者には凄くわかりづらいと思った。
=~
正規表現を使うとき。初心者の頃は意外と間違えて=を使ってしまう。
$test =~ s/hoge/huga/;
. (ドット)
文字列を連結するときに使う。
print 'hoge'.'huga'; print $str1 . $str2 . 'hello' . $str3;
.=, +=
イコールの前の演算子で左辺と右辺を演算した結果を左辺に代入する。以下はそれぞれ、上下で同意。
$hoge .= 'ほげ'; $hoge = $hoge . 'ほげ';
$num += 5; $num = $num + 5;
$param ||= 'デフォルト'; $param = $param || 'デフォルト';
..
連続したリストを作成できる範囲演算子です。数値のリストは私は結構頻繁に使います。以下のようにかけば、1から10までの数値処理を行うことができます。
for(1..10){ print; }
文字列にも適用できます。たとえば以下のように書けば、エクセルの列名のような結果が得られます。
print join ",", ('A'..'ZZ');
DATA
この特殊ファイルハンドルを覚えた時は開発効率がグッとあがったのを覚えています。__DATA__トークン、__END__トークン以降のデータを読み出すことのできるファイルハンドルです。
Perlは__DATA__トークン、__END__トークン以降のスクリプトは実行しません。以下は__END__以降を出力するプログラムです。
#!/usr/bin/perl -w use strict; print <DATA>; __END__ 我輩は犬である。 早く人間になりたい。
変数の値を交換する
この方法を知ったときは結構嬉しかったです。昔は態々swap関数を書いたりしてました。VBSのページのソートのコードでも、値の交換を使っていますが、交換用の変数を使うのが一般的です。Perlでは、
($hoge, $fuga) = ($fuga, $hoge); ($var1, $var2, $var3, $var4) = ($var4, $var3, $var2, $var1);
のように、リストにリストを代入することができます。PHPでのやり方も書いておきましたが、関数指定なのでちょっとイケてません。:-(こういう書き方をする時のPerlは美しくてよいですなぁ。
#!perl -w # swap.pl - 変数の値を交換する use strict; my $hoge = 'Hogege'; my $fuga = 'Fugaga'; ($hoge, $fuga) = ($fuga, $hoge); print "\$hoge = $hoge\n"; print "\$fuga = $fuga\n";
複数行の文字列を一気に読み込む
特殊変数 $/ を未定義にすることで全入力を一気に読み込みます。
local $/;
特殊変数 $/ は、入力レコードの区切り子で、デフォルトでは改行文字になっています。そのため通常の何も指定しない状態では改行ごとに区切って読み込みます。
#!perl -w use strict; local $/; my $text = <DATA>; print $text; exit; __DATA__ この文章は一行目の文章です。 この文章は二行目の文章です。 この文章は三行目の文章です。 この文章は何行目の文章でしょう?
これを知っていると、複数行の正規表現で重宝します。一気に読み込み、一発置換!とか・・・結構使えます。 :-)
$text =~ s/文章/文字列/g;
x演算子
文字列の繰り返しを行います。こんなの見ると、Perlってなんでもアリなんだなぁ・・・とツクヅク思いますなぁ。
print "\n" x 10; # 10行改行 print "123" x 5; # 123123123123123 print 6 x 6; # 666666 print '.' x 10; # ..........
Pathの指定方法
そういえば、私は初めてPerlに触れた時、Windowsのパスの指定方法を、hoge\\fuga などとやっていました。参考書とかろくに読まなかったのでこのような表記をしていたのですが、hoge/fuga とUNIXと同じように書けること気づいたのは、CGIの開発を始めてからでした。(^^;
#!perl -w # winpath.pl - WindowsでのPath指定サンプル use strict; #open(FILE, 'hoge\\fuga\\foo.txt') or die; open(FILE, 'hoge/fuga/foo.txt') or die; print while <FILE>; close(FILE);
配列内容のクリア
教えられると「なーんだ」と思いますが、結構探すのが大変だったので書いておきます。連想配列も同様。
@hoge = (); %fuga = ();
のように空のリストを代入します。:-)
ハッシュ(連想配列)の初期化
初めはこんな感じで初期化を覚える。
my %hash1; $hash1{'NAME'} = 'tuka'; $hash1{'URL'} = 'http://tuka.s12.xrea.com/'; $hash1{'TITLE'} = 'つかのぺ';
しかし上記の方法では、$hash{KEY}= をいちいち書かなくてはならず面倒です。ハッシュではリストを代入すると、キーと値の2つ1組として連想配列に取り込めます。
my %hash2 = ( 'NAME', 'tuka', 'URL', 'http://tuka.s12.xrea.com/', 'TITLE', 'つかのぺ' );
ちょっとわかりやすくなりました。リストなので、
my %hash3 = qw(NAME tuka URL http://tuka.s12.xrea.com/ TITLE つかのぺ);
のようにqwを使ったりしてもOKです・・・がとても解りづらいので止めたほうがよいです。カンマの代わりに =>演算子を使うともっとわかりやすくかけます。
my %hash4 = ( 'NAME' => 'tuka', 'URL' => 'http://tuka.s12.xrea.com/', 'TITLE' => 'つかのぺ', );
通常は上記の書き方で初期化すればよいでしょう。
尚、=> はカンマの代わりなので、以下のようにも初期化できますが、絶対止めた方がよいです。:-)
my %hash5 = ( 'NAME' => 'tuka' => 'URL' => 'http://tuka.s12.xrea.com/' => 'TITLE' => 'つかのぺ' => );
ちゃんと初期化できたかな?
my $key; print "-----hash1-----\n"; foreach $key (keys %hash1){ printf("%5s = %s\n", $key, $hash1{$key}); } print "-----hash2-----\n"; foreach $key (keys %hash2){ printf("%5s = %s\n", $key, $hash2{$key}); } print "-----hash3-----\n"; foreach $key (keys %hash3){ printf("%5s = %s\n", $key, $hash3{$key}); } print "-----hash4-----\n"; foreach $key (keys %hash4){ printf("%5s = %s\n", $key, $hash4{$key}); } print "-----hash5-----\n"; foreach $key (keys %hash5){ printf("%5s = %s\n", $key, $hash5{$key}); }
ファイルテスト演算子
ファイルテスト演算子は頻繁に使うと思います。Perlを始めた頃は、この構文(というか書き方)を理解できませんでした。結局なんでもアリみたいな。流石Perlだ。
で、この演算子を使ってファイルを色々テストできます。よく使うのは、
演算子 | テスト内容 |
---|---|
-e | ファイルが存在する |
-d | ディレクトリである |
-s | ファイルサイズを返す(バイト) |
とか。便利なので、書き方を覚えましょう。サンプルです。大体このように使います。
#!/usr/bin/perl -w # filetest.pl - ファイルテスト演算子 use strict; my $FILE = 'testfile.txt'; if(-e $FILE){ print $FILE . 'は存在します。' . "\n"; print 'ファイルサイズは', -s $FILE, 'バイトです。' . "\n"; }else{ print $FILE . 'は存在しません。' . "\n"; } if(-f $FILE){ print $FILE . 'は普通のファイルです。' . "\n"; }elsif(-d $FILE){ print $FILE . 'はディレクトリです。' . "\n"; }else{ print $FILE . 'は怪しいファイルかも・・・(^^;' . "\n"; }
あと、-M とかも使ったりするかな。-Mはファイルの更新時刻から現在までの時間を日数で返します。(なんつー仕様じゃ・・・)
秒数へ変換するには、1日の秒数を(24 * 60 * 60)をかけて time値から引けばよいでしょう。
$tm = -M $FILE; $timestr = localtime(time - $tm * 24 * 60 * 60); print $timestr;
とか。まあ、この変換で使うことより、時刻の比較で使うことの方が多いかもしれません。ファイルリストを更新時刻順に並べたりするには、
sort {-M $a<=>-M $b} @filelist;
のようにすると簡単です。:-)