############################### # # # コーディング上の注意事項 # 00.1.10 # # ############################### ########## 間違った変数の記述例 ########### print "aaa'.$a[0].'"; # aaa'1'となる print "aaa\"$a[0]\""; # aaa"1"となる print "aaa'$a[0]'"; # aaa'1'となる print 'aaa\"$a[0]\"'; # aaa\"$a[0]\"となる ### 文字変数の場合 ### $a = "テストデータ"; # 1つ表示 print "$a"; print $a;でもOK テストデータ と表示する print '$a';は $a と表示される # 途中で表示 print 'aaa'.$a.''; # 改行して表示 print 'aaa'.$a.''."\n"; print 'bbb'.$a.''."\n"; # 表示を少数点第2までとする $a=1.2345; $b=sprintf("%.2f",$a); print $b; # 文字をつなげる $a="1234"; $b="abcd"; $c="xyz"; $d=$a.$b.$c; # $dは 1234abcdxyz # この方法と $d="$a$b$c"; # ダブルコーテーション""で囲む方法がある # .=を使うと左辺の文字に続けて足されていく $a.=$b; # 1234abcd $a.=$c; # 1234abcdxyz # もちろん $a.=$b.$c でも同じ # $aは 1234abcdxyzと後ろに続けて足されていく ######## 決めた桁数を取り出す ######## # 2桁の場合 # (1)1桁なら左に0をつける $day=1; if ($day < 10) { $day = "0$day"; } # (2)2桁として取り出す $day = sprintf("%.2d",$day); # 変数に文字を足して、左端からとる $a=10; print substr("****".$a,0,5); ****1となる print substr($a."****",0,5); 10***になる $a=1234567; print substr($a,0,5); 12345になる # 変数に文字を足して、右端からとる $a=10; print substr("****".$a,-3,3); *10になる print substr($a."**",-3,3); 0**になる # 末尾からとる $a=1234567; print substr($a,-5,5); 34567になる # 整数部をとりだす $a=1.23456; ($seisu,$dummy)=split(/\./,$a); print $seisu; # こちらの方がスマートです #990710 $seisu=sprintf("%.0f",$a); # または $seisu=sprintf("%.0d",$a); # sprintf("%.0f",$*)は$*の小数点以下を0f 1f 2f 3f で指定できます # 0f -> 1 1f -> 1.2 2f -> 1.23 # sprintf("%.0d",$*)は$*の整数部の頭に(小数点以下無視)0を付けて指定した桁にします # 0d -> 1 1d -> 1 2d -> 01 # 指定文字以降をとりだす $a="12345.6.7.890"; $b=substr($a,index($a,".")+1); これは、$b="6.7.890"となる # 少数点以下4桁をとりだす $a="0.12345678"; $b=substr($a,index($a,".")+1,4); # ディレクトリーを変数にした場合の例 $dir="http://www0.kumagaya.or.jp/chichibu/gazo/"; print '
'; # 月の頭に0があった場合の消去方法 $ym=19980110; $yy=substr($ym,0,4); $mm=substr($ym,4,2); $x=index($mm,"0"); if ($x == 0) { $mm=~ s/0/ /; } $ym=$yy."年".$mm."月"; #これで01月は 1月となる #### 配列の使い方 #### # 配列は、2種類あります # 添え字に数字のみ使える一般のものを配列と呼び、$a[添え字]となります この添え字は0から始まります # この配列の初期化は @a=(); # もう一つは添え字に文字でも数字でも使えるもので連想配列と呼び、$a{添え字}となります よく見るとカッコの記号が違います # この配列の初期化は %a=(); ################### 配列 ############################ # 配列にデータをセットする方法 #1.ひとつひとつセットする $a[0]=1; $a[1]=2; $a[2]=3; $a[3]=4; #2.一度にセットする @a = (1,2,3,4); #ここで注意するのは、配列の添字は0から始まります #よって、$a[1]=100; $a[2]=200;のように1から始めたつもりでも配列の要素数は3つとなります # 配列の要素の数を得る(1) #@aの配列ならば、$#a (#を入れます)に最後の添字が入りますが、添字0があるので # $#a + 1 が求める要素数になります @a = (1,2,3,4); なら $#a には 3が入ります # 配列の要素の数を得る(2) #もっと簡単な方法は $b=@a; @a = (1,2,3,4); なら # この$bには 4が入ります # 配列データ1つを表示させる場合 @a = (1,2,3,4); print $a[0]; # 改行させて表示させる場合 print $a[0]."\n"; print $a[1]."\n"; #### 配列データをHTMLタグの中で使用する場合 print 'aaa'.$a[0].''; # aaa1となり正しく変数が表示される # 改行させる print 'aaa'.$a[0].''."\n"; print 'bbb'.$a[1].''."\n"; # aaa1 # bbb2となり正しく変数が表示され、改行される # 'マークがかさなる場合は、\でエスケープする print '$ENV{\'SERVER_SOFTWARE\'}='.$ENV{'SERVER_SOFTWARE'}."\n"; # 配列のカッコ内に計算式が使えます $a[$b-1]; ################### 連想配列 ############################ $ymd="0901"; $memo{'0901'}="テスト"; print $memo{$ymd}; # テスト と出る $a{'1'}=10; $a{'2'}=20; $a{'3'}=30; print %a; 110220330となる $a{'1'}=10; $a{'2'}=20; $a{'3'}=30; delete $a{'3'}; print %a; 110220となる ここで大切なのは個々に連想配列を作っても、%で全要素を処理できる # 連想配列にセットした個々のデータをファイル登録するリスト形式に直す $a{'1'}=10; $a{'2'}=20; $a{'3'}=30; while(($aa,$bb)=each(%a)) { $value="$aa\,$bb\n"; push(@new,$value); } print @new; とすると 1,10 2,20 3,30 となる、これを print *** @new;としてファイルに書き込む これと次は同じ結果になる foreach (@a) { $value = "$_\,$a{$_}\n"; push(@new,$value); } # キー部を昇順にソートする $a{'3'}=30; $a{'2'}=20; $a{'1'}=10; @new=sort sort keys(%a); print @new; sub sort { $a cmp $b; } # キー部が123になる # キー部を降順にソートする場合は $b cmp $a とする # キー部が321になる # 改行コード\nで連結された文字列を各行に分ける $a='111\n222\n333\n444'; @disp = split(/\n/,$a); foreach (@disp) { print $_."\n"; } # 文字列を1文字ずつ配列にセットする $a="12345"; @b = split(//,$a); $b[0]には1が、$b[1]には2が、$b[2]には3が入る # 配列の要素の数は $a=@b; で求められる 上のデータとすると $aには 5 # 配列の最後の添え字は $a=$#b; で求められる 上のデータとすると $aには 4 # つまり配列は0から始まっているから0〜4となる # よって $#b+1 でも要素の数は求められる # 配列の一番目に要素を挿入する(セットする) unshift(@a,$a,$b,$c,,,,) # 例えば@a=(4,5,6)で unshift(@a,1,2,3) なら @a=(1,2,3,4,5,6) となる # 配列の一番目の要素を取り除く shift(@a); # 配列を連続処理するには foreach(@***) { } を使います・・・この形の場合 $_という特殊変数に配列データが入ります # 金額を表わす3桁カンマを入れる $a="1234567"; @b = split(//,$a); $i=@b; $i--; $c=0; $aa=""; for ($j=$i ;$j>=0;$j--) { $c++; $aa=$b[$j].$aa; if ($c ==3 && $j>0) {$aa=",$aa";$c=0} } # end of for print $aa; # ここで $aaは 1,234,567 となる # もっとかっこいい方法 # 潟oンテック情報システム部 火星人さんより $tt=""; while (length($a)>0){ $tt=chop($a).$tt; if (($tt=~/^\d{3}/)&&length($a)>0){$tt=','.$tt;} } print $tt; ################################################################################ # if文について # { }の置き方 if (条件文) { 実行文 } # この書き方が教科書通りですが if (条件文) { 実行文 } # この方がわかりやすいときも多い # 多重if (COBOL風表現) if (条件文A) { if (条件文B) { 実行文 } } # 条件AとBが成立するなら実行 if (条件文A && 条件文B) { 実行文 } # これも同じ結果となる if (条件文A || 条件文B) { 実行文 } # これは条件A OR Bなら実行文 # 例 $aが1以下または10より大ならerrorと表示する if ($a <= 1 || $a > 10) {print "error"} # 数値として比較する場合と文字列として比較する場合の比較演算子の使い分けに注意 <比較> <数値> <文字列> 等しい == eq 等しくない != ne より小さい < lt より大きい > gt より小さいか等しい <= le より大きいか等しい >= ge ここで $a=2; $b=100; if ($a < $b) {print "bの方が大きい";} # 成立する (数値として比較) if ($a lt $b) {print "bの方が大きい";} # 成立しない(文字列比較で2より1の方が小さい) # よくif文の中に、eq が使われるが数値か文字かで判断がかわらないか ここで $a=1; $b=001; if ($a == $b) {print "数値として等しい";} # もちろん成立 if ($a eq $b) {print "文字列として等しい";} # これも成立する $bは数値だから では $a="1"; $b="001"; if ($a == $b) {print "数値として等しい";} # 変数は文字であるが数値として成立 if ($a eq $b) {print "文字列として等しい";} # 成立しない 文字列比較だから # 例1 $a=12345678; # これは8文字です # 間違い if (length($a) le 10) { # 真にはならない } # 正解 if (length($a) < 10) { # 真になる } # 条件式内に式を置くこともできる # 例1 if ($c * ($a+$b) > 10) {*******} # カレンダー内の休日判別 %a=(0101,1,0115,1,0505,1,0721,1); $mm=1; $dd=1; # 2桁にする $mm = sprintf("%.2d",$mm); $dd = sprintf("%.2d",$dd); # 文字列判定 if ($a{$mm.$dd} eq 1) {print "休日です";} # 指定文字列の存在チェック $a="abcde"; if ($a =~ /abcde/) {print "真です"; } # 否定文では $a="abcde"; if (!($a =~ /abde/)) {print "偽の否定ですとなりこのprint文は実行します";} # 指定された数字(0−9)が含まれるかのマッチ処理 $a="111.222.ccc"; if ($a =~ /[0-9]/) {print "真"; } if ($a =~ /\d/) {print "真"; } # 指定された文字(小文字、大文字)が含まれるかのマッチ処理 $a="aaa.bbb.333"; if ($a =~ /[a-zA-Z]/) {print "真"; } if ($a =~ /\w/) {print "真"; } # \w は英数字を対象とする # 数字以外が含まれていないなら真 $a="111.222.333"; if ($a =~ /[^a-zA-Z]/) {print "真"; } # 数字とピリオド以外が含まれているなら真 if ($a =~ /[^0-9.]/) {print "真"; } # 数字とピリオド以外があるか調べる方法2 $a =~ s/[0-9.]//ig; # すべて消す if ($a eq "") { すべて数字以外なかったことになる } ################################################################################ # テーブルにデータがないときの初期化方法(1) while ($#data + 1 < 15) { @data = (0,@data); } ################################################################################ # 処理を繰り返す方法(1) # 例えば10回 $a=1; while ($a<=10) { # この{ }の中の処理が繰り返される print '処理回数:'.$a.''."\n"; $a++; } # 処理を繰り返す方法(2) $a=1; until($a>10) { # この{ }の中の処理が繰り返される print '処理回数:'.$a.''."\n"; $a++; } # 処理を繰り返す方法(3) for ($a=1; $a<=10; $a++) { # この{ }の中の処理が繰り返される print '処理回数:'.$a.''."\n"; } # 処理を繰り返す方法(4) $a=1; &syori until $a > 10; # この式が単体で文になるので記述可 sub syori { # この{ }の中の処理が繰り返される print '処理回数:'.$a.''."\n"; $a++; } # 偶数で繰り返し for ($a=0; $a<=8; $a=$a+2) {print $a ;} これは、0 2 4 6 8 なる # +1ずつ繰り返す for (1..10) {命令} 命令を10回繰り返す # 変数も使える $a=1; $b=10; for ($a..$b) {命令} 命令を10回繰り返す ##### 繰り返し文からの抜ける方法 # lastを使う for ($a=1; $a<=10; $a++) { if ( 条件文 ) { *****; *****; last } } # ここから抜けて次を実行する # gotoを使う(for文の繰り返し状態を残したまま飛ぶので要注意です) for ($a=1; $a<=10; $a++) { if ( 条件文 ) { *****; *****; goto aaa } } aaa: 次の命令文 # 途中を飛び越してラベルaaaへ行く # 注として、ここに来た状態でも($a=1; $a<=10; $a++)の値はそのまま持っている # よって次にまたfor文を実行する場合は直前の変数を終了条件の値にセットし次の変数を変えること # コボルで私がよく使う繰り返しのパターン $a=1; aaa: print $a; if ($a < 20) { $a++; goto aaa; } # 次の例は、サブルーチンから強制的に抜けてループする処理(サブルーチンからも抜けられるという例) $a=0; aaa:print $a; &abc; sub abc {$a++;if ($a < 20) {goto aaa;}} ############################ # フォーム入力データを配列にセット $n=0; @cnt=""; $in{'cnt1'}=10; $in{'cnt2'}=20; $in{'cnt30'}=999; # 入力値がなければ0にする until ($n > 29) { if ($in{'cnt'.$n.''} eq "") {$in{'cnt'.$n.''} = "0";} push(@cnt,$in{'cnt'.$n.''}); $n++;} # 結果は、01020000000.... 999は入らない # フォーム入力された各項目を1変数に入れる $n=0; $cnt=""; $in{'cnt1'}=10; $in{'cnt2'}=20; $in{'cnt30'}=999; until ($n > 29) { if ($in{'cnt'.$n.''} eq "") {$in{'cnt'.$n.''} = "0";} $cnt=$cnt.$in{'cnt'.$n.''}.","; $n++;} # 結果は、0,10,20,0,0,0,......0, となり ,で終わる ################################################################################ # 数字以外が含まれているかのチェック # ^を付けて数字以外 $a="100ア"; if ($a =~ /^\d/) { print "$a には数字以外が含まれています"."\n"; } # 数字の否定形 $a="100ア"; if ($a =~ /\D/) { print "$a には数字以外が含まれています"."\n"; } # 等価なクラス $a="100ア"; if ($a =~ /[^0-9]/) { print "$a には数字以外が含まれています"."\n"; } ###### メールアドレスチェック ######## # 英数字と@と.と_と- $a="Test@pro.or.jp*"; if ($a =~ /[^a-zA-Z0-9@._-]/) { print "$a には指定文字以外が含まれています"."\n"; } # 英数字と@と.と_と-(大文字と小文字の違いを無視するiフラグ) $a="Test@Abc.or.jp"; if ($a =~ /[^a-z0-9@._-]/i) { print "$a には指定文字以外が含まれています"."\n"; } # @と.の順番をチェック (******@***.***の形) $a="Test@Abc.or.jp"; if ($a =~ /.*@.*\..*/) { print "$a の指定文字の順序は正しい"."\n"; } else { print "$a の指定文字の順序がおかしい"."\n"; } ############################################# # 今日の曜日から1日の曜日をだす ($t1,$t2,$t3,$t4,$t5,$t6,$t7)=localtime; # 指定日から1日までさかのぼりながら曜日を求める $sy=$t7; for ($i=$t4; $i>1; $i--) { # 曜日も1日前へここで0(日曜)より前になったら6(土曜)に戻る $sy--; if ($sy < 0) { $sy = 6 } } # end of for print $sy; ############### ランダム関数 ################ # 配列の中からランダムに要素を取り出す @t=(1,2,3,4,5); srand; print $t[rand(@t)]."\n"; # これは1から5までの数字が出ます @t=(a,b,c,d,e); srand; print $t[rand(@t)]."\n"; # これはaからeまでの英字が出ます ################ sort ################### # 日付順にソートする %t=(19970505,"こどもの日",19970101,"元旦",19970220,"春分の日"); @key=keys(%t); @new=sort sortsb @key; foreach (@new) { print $_." ".$t{$_}."\n"; } sub sortsb { $a <=> $b; } # 結果は 19970101 元旦 19970220 春分の日 19970505 こどもの日 と表示される #################################################################################### # フォーム入力時に文字数を限定させ無意味なデータを受け付けないようにする # 例、フォームの入力欄の大きさを半角で10文字、最大入力数を半角で15文字とする あなたのお名前は? # 但し、TEXTAREAは限定できないので受け取り側のCGIで文字数チェックする ##### 置換演算子 ##### # タグの無効化(記号の大小かっこを文字のかっこに変える) # オプションiは大文字と小文字を区別しないで置換します # オプションgは文字列を最後まで処理します $msg =~ s/</ig; $msg =~ s/>/>/ig; $msg =~ s///ig; # 数字以外を除く $a="123.45"; $a=~s/[^0-9]//g; は $a=~s/\D//g; でも良い(略記法) print $a; # 12345となる # TEXTAREAから入力されたデータについては改行コード\n以外のコードが付くので # 改行コードを\nに統一する $naiyo=~ s/\015\012/\n/g; # Windowsから $naiyo=~ s/\015/\n/g; # Macから # TEXTAREAから入力されたデータについて2行以上空いたら1行にする # 不要な改行をカットする # s/\nの¥nは1行目文字列の改行コードを想定しています、1行目が空行の場合残ってしまいます # 空行も許さない場合 $a=~s/\n\n*/\n/g; # 空行を1行までは許す場合 $a=~s/\n\n\n*/\n\n/g; # 空行を2行までは許す場合 $a=~s/\n\n\n\n*/\n\n\n/g; # *は以上を示します、例えば下の場合 $a='aabbaabbbaabbbbbbbbbbb'; # bが3つ以上並んでいる場合、bを2つにするという置換命令です $a=~s/bbb*/bb/g; print $a; $aは、aabbaabbaabb になります ########################## # デコードルーチン # ########################## sub jdecord { $ENV{'REQUEST_METHOD'} =~ tr/a-z/A-Z/; if ($ENV{'REQUEST_METHOD'} eq "POST") { read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); } else { $buffer = $ENV{'QUERY_STRING'}; } @pairs = split(/&/, $buffer); foreach $pair (@pairs) { ($name, $value) = split(/=/, $pair); $value =~ tr/+/ /; $value =~ s/%(..)/pack("C", hex($1))/eg; $value =~ s/</g; $value =~ s/>/>/g; &jcode'convert(*value,'sjis'); $in{$name} = $value; } } # end of jdecord ################################################################################