◆ Perl の文法
◇ 基礎知識
それぞれの行を statement
と呼ぶ。statement
の末尾には「;
」(セミコロンをつける)。statement
は上から順番に実行されていく。通常の変数には $
を付けて表わす。数値は以下の形式を使用できる。
- 12345:整数
- 12_345:整数(アンダーバーは無視される)
- 123.45:小数
- 1.23E45:指数
- 012345:8進数
- 0x12345:16進数
文字列はダブルクォーテーション、またはシングルクォーテーションで囲む。ダブルクォーテーションの中では変数やバックスラッシュが評価されるが、シングルクォーテーションの中では純粋な文字として認識される。
$str = "SevenKey"; print ">$str\n"; print '>$str\n';
>SevenKey >$str\n
変数名にはアンダーバーを含む半角英数文字を使用することができるが、最初の1文字は数値であってはならない
(駄目例) $seven-key $7key
perlでは、数値と文字列の扱いはあいまいで、その都度数値として評価されたり、文字列として評価されたりする。
真偽判断では、(""), (0), ("0")は偽として、それ以外は真として扱われる。true
や false
という特殊な変数がある訳ではなく、return(false)
は、"false"
という文字列を返すだけである。真偽を返却する関数を評価する際は if (&samp()){}
と評価する。
変数には定義済みの状態と未定義の状態がある。最初は未定義だが、最初に何か値が代入されると定義済みになる。定義済みかどうかを調べるためには defined()
を使用する。
perlには省略の美学というものがあり、いろいろな場面で変数名を省略することができる。省略した場合は、$_ を指定したものとみなされる。
while (<IN>)
while ($_ = <IN>)
print;
print $_;
/^From:/
$_ =~ /^From:/
while () { if (/^From:/) { print; } }
while ($exp =) { if ($exp =~ /^From:/) { print $exp; } }
◇ 演算子
算術演算子
- $lng = 7 + 3;
- 和
- $lng = 7 - 3;
- 差
- $lng = 7 * 3;
- 積
- $dbl = 7 / 3;
- 商
- $lng = 7 % 3;
- 余(=1)
- $lng = 7 ** 3;
- 乗(=343)
- $lng++;
- $lng = $lng + 1
- $lng--;
- $lng = $lng - 1
ビット演算子
- $strX | $strY
- $strX と $strY のOR
- $strX & $strY
- $strX と $strY のAND
- ~$strX
- $strXのビットをすべて反転させる
- $strX << 2
- $strX を2ビット左シフト
- $strX >> 2
- $strX を2ビット右シフト
数値比較演算子
- if ($lngX == $lngY)
- $lngX と $lngY が等しいとき
- if ($lngX != $lngY)
- $lngX と $lngY が等しくないとき
- if ($lngX <= $lngY)
- $lngX が $lngY より等しいか小さいとき
- if ($lngX >= $lngY)
- $lngX が $lngY より等しいか大きいとき
- if ($lngX < $lngY)
- $lngX が $lngYより小さいとき
- if ($lngX > $lngY)
- $lngX が $lngY より大きいとき
- if (($lngX==2) && ($lngY==7))
- $lngX が 2 且つ、$lngY が 7 であれば
- if (($lngX==2) || ($lngY==7))
- $lngX が 2 又は、$lngY が 7 であれば
- if ($lngX <=> $lngY)
- 比較結果を -1, 0, 1 のいずれかで返す
文字列比較演算子
- if ($strX eq $strY )
- $strX と $strY が等しいとき
- if ($strX ne $strY )
- $strX と $strY が等しくないとき
- if ($strX le $strY )
- $strX が $strY より等しいか小さいとき
- if ($strX ge $strY )
- $strX が $strY より等しいか大きいとき
- if ($strX lt $strY )
- $strX が $strY より小さいとき
- if ($strX gt $strY )
- $strX が $strY より大きいとき
- if ($strX =~ /KEY/)
- $strX が KEY という文字を含むとき
- if ($strX !~ /KEY/)
- $strX が KEY という文字を含まないとき
- if ($strX cmp $strY )
- 比較し、-1, 0, 1 のいずれかで返す
範囲演算子
- @samp = (1 .. 5);
- @samp = (1, 2, 3, 4, 5); と同様
- for (1 .. 5)
- for ($_ = 1; $_ <= 5; $_++) と同様
反復演算子
- print 'K' x 5;
- KKKKK
- $str x= 5;
- $str を 5 回繰り返したものを $str に代入
- @samp = (K) x 5;
- (K, K, K, K, K)同様
文字列連結
- $strX = $strY . $strZ;
- 文字列 $strY と 文字列 $strZ を連結する
- $strX .= $strY;
- $strX = $strX . $strY と同様です
◇ スカラー変数
( $ )で始まる変数はスカラー変数と呼ばれる。スカラー変数には数値又は文字列を一つ代入することができる。通常、初期化していない変数は NULL
または 0 として扱われるが、処理系によっては誤動作を起こすことがあるらしいので最初に $lng = 0;
と初期化しておいた方がよい
$samp = 7; $samp = 'Key';
◇ 配列
配列は $変数名[添え字]という形式で個々の要素を操作したり、( @ )を用いて配列全体を操作したりすることができる。添え字には正の整数値(0 含む)を指定する。配列同士の一括代入も可能である
$sampX[0] = 7; $sampX[1] = 'Key'; ( $year, $mon, $day ) = ( 1977, 7, 7 ); @samp = ( 'a', 'b' ); $samp[2] = 'c'; @samp[3..4] = ( 'd', 'e' ); print @samp;
>a b c d e
$#exp は、@exp の配列の最後の添え字(個数から1をひいたもの)を表わす
@samp = ( 'a', 'b', 'c', 'd', 'e'); print "$#samp\n";
>4
()は空配列を示す。
@samp = ();
配列を操作するための関数
- shift(@exp);
- 最初の要素を取り除き、これを返す
- pop(@exp);
- 最後の要素を取り除き、これを返す
- push(@exp, $samp);
- 最後に要素を追加する
- push(@exp1, @exp2);
- @exp1 の後ろに @exp2 の要素を追加する
- splice(@exp, 3, 2);
- $exp[3..4](2個)を取り除き、これを返す
- reverse(@exp);
- @exp の要素を逆順にしたものを返す
- sort(@exp);
- @exp の要素をソートした結果を返す
- @exp = split(/<>/, $samp);
- 文字列 $samp を"<>"で分割し、その配列を返す
(追記)
#すべての配列要素について処理を行う foreach $i (@exp) { print "$i\n"; }
◇ 連想配列
$変数名{文字列}という形式で、文字列を添え字とした配列を操作できる。%変数名 という形式で、連想配列全体を操作できる。
$exp{"Jan"} = "1st"; $exp{"Feb"} = "2nd"; %exp = ( "Jan", "1st", "Feb", "2nd" );
(追記)
#すべての連想配列要素について処理を行う while (($name, $value) = each(%xx)) { }
◇ 環境変数
%ENVという特別な連想配列変数を用いて環境変数の値を読み取ったり設定したりすることができる。
GATEWAY_INTERFACE | サーバが使用するCGIのレビジョン情報 |
SERVER_ADMIN | ウェブサーバ管理者のメールアドレス情報 |
SERVER_NAME | サーバのホスト名、ドメイン名、またはIPアドレス情報 |
SERVER_PORT | リクエスト送信に使われたポート番号 |
SERVER_PROTOCOL | リクエスト送信に使われたプロトコルの名前とレビジョン情報 |
SERVER_SOFTWARE | CGI プログラム を起動したサーバソフトウエアの名前とバージョン情報 |
CONTENT_LENGTH | POSTから標準入力に送信されたデータのバイト数 |
CONTENT_TYPE | POSTとPUTなどのクエリに添付されたデータのMIMEタイプ |
DOCUMENT_ROOT | 実行されているスクリプトの仮想パス |
PATH | UNIXコマンドを起動するディレクトリ |
PATH_ INFO | クライアントから送られるエキストラパス情報 |
PATH_TRANSLATED | ウェブサーバのドキュメントルートに環境変数PATH_INFOを追加した情報 |
QUERY_STRING | クエリとして送られたURL情報のクエスチョン以降の情報 データはURLエンコードされている |
REQUEST_METHOD | リクエスト送信方法(GETやPOSTなど) |
SCRIPT_FILENAME | CGI プログラムのファイル名も含めた絶対パス情報 |
SCRIPT_NAME | CGI プログラムのルートディレクトリ以降のパス情報 |
AUTH_TYPE | ユーザを認証するときに使用する認証メソッド ウェブサーバとリモートホストがユーザ認証プロトコルを実行しているときだけ値がある |
PATH_TRANSLATED | CGIプログラムに渡されるエキストラパス情報 |
HTTP_FROM | リクエストを出しているユーザの電子メールアドレス ほとんどのブラウザでは、この変数をサポートしていない |
HTTP_ACCEPT | クライアントが受け付けることができるMIMEタイプのリスト |
HTTP_USER_AGENT | クライアントがリクエストを発行するときに使用するブラウザ名 |
HTTP_REFERER | 呼び出し元のURL アドレスバーからの直接入力、ブックマークからのアクセスの際には値がない |
REMOTE_ADDR | リモートホストのIPアドレス情報 |
REMOTE_HOST | リモートホストのドメイン名 |
REMOTE_IDENT | リモートホストのユーザ名 |
REMOTE_USER | ユーザの認証名 ウェブサーバとリモートホストがユーザ認証プロトコルを実行しているときだけ値がある |
#環境変数の列挙 #!/usr/local/perl print "Content-type: text/html\n\n"; print "<html><head><title></title></head><body>\n"; foreach my $key( keys %ENV ){ print "$key: $ENV{$key}<br>\n"; } print "</body></html>", "\n";
#ブラウザ判別 #!/usr/local/perl print "Content-type: text/html\n\n"; my $agent = $ENV{'HTTP_USER_AGENT'}; if ( $agent =~ /^Mozilla/ ){ if ( $agent =~ /^Mozilla\/[0-9\.]+\s\(compatible\; MSIE/ ){ print "IE\n"; } else { print "NN\n"; } } else { print "OTHER\n"; }
#ドメイン判別 #!/usr/local/perl print "Content-type: text/html\n\n"; my $host_address = 'sevenkey\.ddo\.jp'; if ( $ENV{'REMOTE_HOST'} =~ /^\.$host_address$/ ){ print "Success in login\n"; } else { print "Failure of login\n"; }
◇ コマンド引数
コマンドラインからの引数を得るために、次の変数が使用できる
@ARGV # 引数の配列 $#ARGV # 配列の個数−1 $ARGV[0] # 最初の引数 $ARGV[$#ARGV] # 最後の引数
◇ シグナル
プログラムに送信される非同期のメッセージ。例えば、強制終了を明示された時はSIGTERMシグナルが、プロセス間の通信が切断された時はSIGPIPEメッセージが、設定しておいた時刻になったらSIGALRMシグナルが、プログラムに対して送信される。
$SIG{'TERM'} = "sigexit";
と宣言することにより、そのプログラムに SIGTERMシグナルが送信された時に、&sigexit()関数が実行されるようになる
◇ 特殊変数
$. | 入力時のレコード区切り文字。通常は改行 |
$, | 出力時の項目区切り文字。print @exp; の時に有効 |
$" | 出力時の項目区切り文字。print "@exp"; の時に有効 |
$\ | 出力時の行末文字。print "$exp"; の後ろに付加される |
$# | 出力時の数値形式。通常は"%.20g"。 |
$% | 出力時の現在のページ番号 |
$= | 出力時の現在のライン数 |
$- | 出力時の残り行数 |
$~ | 出力時のフォーマット名 |
$^ | 出力時のヘッダフォーマット名 |
$| | 0以外が代入されると出力をバッファリングしなくなる |
$$ | プロセスID |
$? | 最後に実行されたコマンドのステータス |
$& | パターンマッチにマッチした部分文字列 |
$` | パターンマッチにマッチした部分の前側の文字列 |
$' | パターンマッチにマッチした部分の後側の文字列 |
$+ | パターンマッチの最後の()に対応する文字列 |
$0 | perlスクリプトのコマンド名 |
$1 | パターンマッチの際の1番目の()に対応する文字列 |
$[ | 配列の最初の添え字 |
$] | perlのバージョン情報 |
$; | 高次元連想配列の添え字の区切り文字 |
$! | エラー番号、もしくはエラー文字列 |
$@ | 直前のevalコマンドのエラーメッセージ |
$< | このプロセスの実ユーザーID |
$> | このプロセスの実効ユーザーID |
$( | このプロセスの実グループID |
$) | このプロセスの実効グループID |
$^D | デバッグフラグの値 |
$^F | システムファイルディスクリプタの最大値 |
$^I | -iオプションで指定した拡張子の名前 |
$^P | デバッガが使用する内部フラグ |
$^T | スクリプトを実行した時刻 |
$^W | 警告スイッチの現在値 |
$^X | perl自身の起動時の名前 |
@_ | サブルーチンへの引数 |
@INC | perlライブラリ検索ディレクトリ |
%INC | 読み込まれたライブラリファイルの配列 |
_LINE_ | スクリプト中の現在の行数 |
_FILE_ | スクリプトのファイル名 |
◇ ファイル検査
ファイルが書き込み可能かどうか等を調べる
if (-w "samp.txt") { }
-r | 読み込み可能チェック |
-w | 書き込み可能チェック |
-x | 実行可能チェック |
-o | 自分のものチェック |
-R | 実uid/gidで読み込み可能チェック |
-W | 実uid/gidで書き込み可能チェック |
-X | 実uid/gidで実行可能チェック |
-O | 実uidのものチェック |
-e | 存在チェック |
-z | サイズチェック |
-s | サイズチェック(ファイルサイズを返す) |
-f | 通常ファイルチェック |
-d | ディレクトリチェック |
-l | シンボリックリンクチェック |
-p | 名前付きパイプチェック |
-S | ソケットチェック |
-b | ブロック型スペシャルファイルチェック |
-c | キャラクタ型スペシャルファイルチェック |
-u | setuidビットチェック |
-g | setgifビットチェック |
-k | stickyビットチェック |
-t | ファイルハンドルが tty としてオープンされていれば |
-T | ファイルがテキストファイルであれば |
-B | ファイルがバイナリファイルであれば |
-M | perl起動時における、ファイルの更新時刻からの日数 |
-A | perl起動時における、ファイルの参照時刻からの日数 |
-C | perl起動時における、ファイルの作成時刻からの日数 |