sironekotoroの日記

Perl で楽をしたい

Perl入学式で勉強して、情報処理試験の問題を解こう!& おまけ

こんにちは

本年はPerl入学式(東京)でサポーターやっておりますsironekotoroです。

このエントリは Perl入学式 Advent Calendar 2017 - Qiita の2日目です。

qiita.com

Perl情報処理試験問題に出ていた事があった

出オチです。

平成18年度 春期 テクニカルエンジニア(情報セキュリティ) 午後I 問題
https://www.jitec.ipa.go.jp/1_04hanni_sukiru/mondai_kaitou_2004h16_2/2004h16a_su_pm1_qs.pdf
問1「Webサイトのセキュリティに関する次の記述を読んで、設問1~4に答えよ。」

ブラウザからユーザーのデータを送信する際、留意すべき知識を問う問題です。
留意しないと、いずれ徳丸先生が来る事態になります。
是非一度チャレンジして見てください。

注意

残念なことに試験問題へのPerlの採用は2011年まで。代わりに入ったのはECMAScriptでした。

情報処理推進機構情報処理技術者試験:新着:情報セキュリティスペシャリスト試験(SC)で出題するプログラム言語の変更について
https://www.jitec.ipa.go.jp/1_00topic/topic_20111026_sc_yougo.html

それって

・・・Perlやっても今の情報処理試験の問題解けないじゃん!
いえいえ、Perlやってると不思議と他のプログラム言語のつくりとか分かるんですよこれが。
プログラム言語はだいたい英語で書かれてますし、大体の言語で if とか for の仕組みが大きく違うわけではないです。

また、この試験問題の巻末に「プログラム言語Perlの用例・解説」があります。
これがPerl入学式で学ぶ内容とほぼ重なっている事に驚きました。
つまり、Perl入学式やってりゃ試験問題程度のコードは読める!

注意:Perl入学式最大の難所、三日目の悪魔、記号がキモい、Perl初心者転がし、等の異名を持つ「リファレンス」は含まれておりません。

まずPerlでプログラムの基本おさえていきましょう!
分からなくなっても、サポーターが質問に答えてくれるのがPerl入学式です。

さて、明日はYAPC::Okinawa 2018 ONNASON で会える好青年、YAPC運営ブログでおなじみの AnaTofuZ 君です。エモい記事に期待です。

blog.yapcjapan.org

おまけ:プログラム言語Perlの用例・解説

巻末の「プログラム言語Perlの用例・解説」を復習の意味も込めて書写してみました。 openの引数が2つしかないなど、今時なコードではないのですが、Perlの基本は抑えられているという印象です。

試験の過去問題の使用に関しての注意書き

なお、この書写はIPAガイドラインを見て、大丈夫と判断して書写・掲載しております。

IPA 独立行政法人 情報処理推進機構情報処理技術者試験:よくある質問
https://www.jitec.ipa.go.jp/1_09faq/_index_faq.html

試験センターで公表している過去の試験問題の使用に関し、許諾や使用料は必要ありません。(ダウンロードでのご利用も特に問題ございません。)
 ただし、以下の留意点を必ず確認の上、ご使用ください。

【留意点】
著作権は放棄していません。
・教育目的など、情報処理技術者試験制度、情報処理安全確保支援士制度の意義に反しない限り、公表されている過去問題を問題集やテキストに使用される際、許諾および使用料の必要はありません。
・出典は明記してください。
 [例]「出典:平成○年度 ○期 ○○試験区分 午前 問1 設問2」
 また、問題の一部を改変している場合、その旨も明記してください。
・公表しているPDF以外の電子データの提供はできません。
 (PDFセキュリティの解除方法は提供できません。)

1.注釈

種類 用例 解説
# # ここにコメントを書く 行末までが注釈となる。

2.リテラル

種類 用例 解説
スカラ 123 10進数 123 である。
スカラ 12.3 10進数 12.3 である。
スカラ 4E-5 10進数 4*10^{-5}である。
スカラ 0x9 16進数 9F である。
スカラ 0147 8進数 147 である。
スカラ 0b010111 2進数 010111 である。
スカラ $var = "hello";
print '$var ', "$var ", `echo world`;
変数var に文字列 "hello" を代入する。文字列のスカラ '$var ', "$var ",`echo world````を出力する。"$var "は変数を展開し、 echo world はコマンドの出力を展開するので、出力は "$var Hello world" ```となる
スカラ \n 制御文字(改行)である。
スカラ \r 制御文字(復帰)である。
スカラ \t 制御文字(水平タブ)である。
リストリテラル ('a','b','c') リスト('a','b','c')である。
リストリテラル ('a','b','c')[0] リスト('a','b','c')の1番目の要素 'a' である。
リストリテラル () 空リストである。
リストリテラル ('a' => 'alpha', 'b' => 'bravo', 'c'=> 'charlie') キー a, b, c, にそれぞれ値 alpha, bravo, charlie を結びつけたハッシュである。
ファイルハンドル STDIN 標準入力である。
ファイルハンドル STDOUT 標準出力である。
ファイルハンドル STDERR 標準エラー出力である。
ファイルハンドル ARGV コマンドラインから指定されたファイル名のリストを順に読み込むためのファイルハンドルである。

3.変数

種類 用例 解説
スカラ変数 $var スカラ変数 var である。
配列変数 @ary 配列変数 ary である。
配列要素 $ary[6] 配列変数 ary の7番目の要素である。
ハッシュ変数 %hash ハッシュ変数 hash である。
ハッシュ要素 $hash{'a'} ハッシュ変数 hash の要素のうち、キー a に結び付けられた値である。
局所的な変数 {my $var;} {} 内を有効範囲とする変数 var の宣言である。
$_ $_ = "abc";
if(/b/) print "match";
パターンマッチの演算子が省略されたとき、 $_ の文字列 "abc" が // 内のパターン b と一致するかどうかを判定し、 "match" が出力される。
@ARGV @ARGV コマンドライン引数のリストを格納する配列変数である。
@_ @_ サブルーチンに渡す引数のリストを格納する配列変数である。

4.演算子

種類 用例 解説
-> $object->method1 オブジェクト object のメソッド method1 を呼び出す。
-> Class->method2 クラス Class のメソッド method2 を呼び出す。
++ $a++ 変数aを評価した後に1を加算する。
-- --$b 変数bから1を減算した後に評価する。
! !$a 変数aの論理否定である。
+(単項) +123 正の数 123 である。
-(単項) -123 負の数 123 である。
=~ $html_contents =~ /<b>/ 変数 html_contents の値に、文字列 "<b>" が含まれている時に真を返す。
!~ $html_contents !~ /<b>/ 変数 html_contents の値に、文字列 "<b>" が含まれていない時に真を返す。
* 314 * 34 314 と 34 の乗算である。
/ 6 / 469 6 を 469 で割る除算である。
% 34 % 6 34 を 6 で割る剰余演算である。
+ 3.14 + 2.72 3.14 と 2.72 の加算である。
- 220 - 8125 220 から 8125 を引く減算である。
. "IPA" . "JITEC" 文字列 "IPA" と "JITEC" の連結である。
<, >, <=, >= 1 < 2 数値 1 と 2 を比較し、演算子の左側が右側より小さいので真を返す。数値の関係演算子には、他に >, <=, >= がある。
lt, gt, le, ge "b" lt "a" 文字列 b と a を比較し、演算子の左側が右側より小さくないので偽を返す。文字列の関係演算子には、他に gt, le, ge がある。
==, !=, <=> 1 <=> 2 数値 1 と 2 を比較し、演算子の左側が右側より大きければ1、等しければ0、小さければ-1を返すので、この場合は-1を返す。数値の比較演算子には、ほかに ==, != がある。
eq, ne, cmp "b" cmp "a" 文字列 "b" と "a" を比較し、演算子の左側が右側より大きければ1、等しければ0、小さければ-1を返すので、この場合は1を返す。文字列の比較演算子には、ほかに eq, ne がある。
&& $x >= 0 && $x < 10 変数xの値が 0 以上かつ10未満なら真を返す。
|| $x < 0 || $x >= 10 変数xの値が 0 未満又は10以上なら真を返す。
.. @card = (1 .. 52) 1 から 52 までの連続する整数を配列変数cardに代入する。
= $a = 1 変数 a に 1 を代入する。
+= $a += 10 変数 a の値に 10 を加算して a に代入する。代入演算子には、他に -=, *=, /=, %= がある。
=>, , %hash = ('a' => 'alpha', 'b' => 'bravo', 'c'=> 'charlie') a にalpha、bにbravo、cにcharlieを結びつけたハッシュをハッシュ変数 hash に代入する
not not $a 変数 a の論理否定である。
and $a < 0 and $b == 0 変数 a が 0 より小さいか、変数 b が 0 と等しいかという二つの関係式の論理積である。
or $a < 0 or $b == 0 変数 a が 0 より小さいか、変数 b が 0 と等しいかという二つの関係式の論理和である。
xor $a < 0 xor $b == 0 変数 a が 0 より小さいか、変数 b が 0 と等しいかという二つの関係式の排他的論理和である。

5.文

種類 用例 解説
if if ($var == 1){
print "a";
}elsif( $var == 2){
print "b";
}else{
print "c";
}
変数 ver の値が 1 なら "a" を、 2 なら "b"を、それ以外なら "c" を出力する。
while $i = 1;
while($i <= 10){
print $i++, "\n";
}
変数 i の値を 1 から 1 ずつ増やし、10回出力する
for for($i = 1; $i <= 10; $i++){
print "$i\n";
}
変数 i の値を 1 から 1 ずつ増やし、10回出力する
foreach foreach $i (1, 3, 5){
print "$i\n";
}
変数 i にリストの各要素 1, 3, 5 を順に代入し、3 回出力する。
next for ($i = 1; $i <= 10; $i++){
next if $i % 2;
print "$i\n";
}
変数 i が 2 で割り切れないとき、ループ本体の next 行より後を実行しないので、偶数を出力する。

6.正規表現

種類 用例 解説
\ / \. \^ \$ \[ \| \+ \* \? \{ \( \) \/ \\ / 次の 1 文字そのものを表す。 " . ^ $ [ | + * ? { ( ) / \" と一致する。
. /www.ipa.go.jp/ 改行文字以外の任意の 1 文字と一致する。 "wwwdipa,go@jp" と一致する。
^ /^ab/ 先頭が "ab" である文字列と一致する。 "abc" と一致するが、 "cab" とは一致しない。
$ /yz$/ 末尾が "yz" である文字列と一致する。 "xyz" と一致するが、 "yza" とは一致しない。
+ /go+d/ 直前の 1 文字 o の 1 回以上の繰り返しと一致する。 "god" や "gooood" と一致するが、 "gd "とは一致しない。
* /go*d/ 直前の 1 文字 o の 0 回以上の繰り返しと一致する。 "gd", "god" や "gooood" と一致する。
? /colou?r/ 直前の 1 文字 u の 0 回又は1回の出現と一致する。"color" 又は "colour" と一致する。
{m} /co{2}l/ 直前の 1 文字 o の 2 回の繰り返しと一致する。"cool" と一致するが、"col" や "coool" とは一致しない。
{m,n} /go{1,3}d/ 直前の 1 文字 o の 1 ~ 3 回の繰り返しと一致する。"god" や "good" と一致するが、"gd" や "gooood" とは一致しない。
(...) /<(h.)>/ () 内の文字列と一致するパターンを部分パターンとしてまとめる。"<h1>" と一致した場合は "h1" が、 "<hr>" と一致した場合は "hr" が、まとめられる。
\1, \2 /<(..)><([bp])>JITEC<\/\2><\/\1>/ 左から順に()内のパターンと一致した文字列が \1, \2 に割り当てられる。"<h1><b>JITEC<b></h1>" と一致するが、 "<td><b>JITEC</p></td>" とは一致しない。
[...] /<h[12r]>/ 内で指定した文字 1, 2 又は r のどれか一つと一致する。"<h1>", "<hr>" と一致するが、"<h3>" や "<HR>" とは一致しない。
[^...] /[^0-9]/ 内で指定した文字 0 ~ 9 以外の 1 文字と一致する。"a" と一致するが、 "3" とは一致しない。
... | ... /\<(a href | img src)=/ | で区切られた "a href" 又は "img src" のどちらか一方と一致する。"<a href=" や "<img src=" と一致するが、"<A HREF" や "<img height=" とは一致しない。

7.サブルーチン

種類 用例 解説
定義 sub greeting{
print "hello Perl\n";
}
"hello Perl" を出力するサブルーチン greeting を定義する
呼出し subroutine ($arg1, $arg2); サブルーチン subroutine を引数 arg1 と arg2 で呼び出す。()を省略して "subroutine $arg1, $arg2;" とする表記もある。
戻り return -1 サブルーチンから抜け出し、値 -1 を返す。

8.モジュール

種類 用例 解説
use use CGI; モジュール CGI を 1 どだけ読み込み、利用可能にする。

9.メソッド呼び出し

種類 用例 解説
-> $object->method1(arg1); 演算子 -> を使って、オブジェクト object のメソッド method1 を引数 arg1 で実行する。
-> Class->method2(arg1, arg2); 演算子 -> を使って、クラス Class のメソッド method2 を引数 arg1 及び arg2 で実行する。

10.文字列操作関数

種類 用例 解説
chomp chomp @lines 配列変数 lines の各要素の末尾にある改行文字を削除する。
eval eval $exp_str; 変数 exp_str の内容をPerlプログラムとして解釈し実行する。
length length $long_str; 変数 long_str に格納される文字列の文字数を返す。

11.配列・ハッシュ操作関数

種類 用例 解説
keys %hash = ('a' => 'alpha', 'b' => 'bravo', 'c'=> 'charlie');
foreach $key (keys %hash){
print "$key\n";
}
ハッシュ変数 hash のキーのリストを取り出し、各キーを出力する。この場合は、 "a", "b", "c" を順不同に出力する。
shift $next = shift @queue; 配列変数 queue の先頭要素を取り除いて詰め、取り除いた値を変数 next に代入する。
sort @pile = sort @jumble; 配列変数 jumble の値を文字列の大小比較によって昇順に整列し、配列変数 pile に代入する。
sort @pile = sort {$b <=> $a} @jumble; 配列変数 jumble の値を文字列の大小比較によって降順に整列し、配列変数 pile に代入する。
split @fields = split ','; $csv; 変数 csv の値をコンマで区切って分割したリストを配列変数 fields に代入する。

12.検索・置換関数

種類 用例 解説
m/.../ 又は
/.../
$html_contents =~ /<b>/i; 変数 html_contants の値が、文字列 "<b>" 又は "<B>" を含んでいるかどうかを判定する。i は、大文字、小文字の区別をしないオプションである。
s/.../.../ $html_contents =~ s/<br>/\n/gi; 変数 html_contants の文字列 "<br>", "<bR>", "<Br>" 又は "<BR>" を改行文字に置換する。g は、一致したすべての文字列を置換するオプションである。
$`, $&, $', $1, $2 'The date is 1970-01-23.' =~ /([0-9]{4})-([0-9]{2})-([0-9]{2})/;
print "String before the date: $`\n";
print "Date: $&\n";
print "String after the date: $'\n";
print "Year: $1\n", "Month: $2\n", "Day: $3\n";
文字列 "The date is 1970-01-23." に対して、一致した文字列、一致した部分の後ろの文字列をそれぞれ変数 `, &, \' に代入する。また、() で囲まれた部分パターンと一致した文字列を、1 番目から順に変数 1, 2, 3 に代入する。これらを利用し、 "String before the date: The date is ", "Date: 1970-01-23", "String after the date: .", "Year: 1970", "Month: 01", "Day: 23" の6行を出力する。

13.入出力操作関数

種類 用例 解説
open open LOG, >>cgi.log; ファイル cgi.log を追記モードで開き、ファイルハンドル LOG に対応付ける。
$line = <USER_FILE>; ファイルハンドル USER_FILE から 1 行を読み込んで変数 line に代入する。
<> @records =<>; 標準入力(コマンドライン引数があるときは、コマンドライン引数で指定されたファイル)から順にデータを読み込み、すべての行を配列変数 records に代入する。
print print LOG "sync.\n"; ファイルハンドル LOG に対応するファイルに文字列を出力する。
close close LOG; ファイルハンドル LOG に対応するファイルを閉じる。

14.入出力操作関数

種類 用例 解説
die open(FILE, 'a_file') or die 'cannot open a_file'; ファイル a_file を開く。開くのに失敗したとき、"cannot open a_file" というメッセージを出力して実行を終了する。
system system 'a.out'; コマンド a.out を実行し、コマンドが終了するまで待機する。