C言語プログラムとほぼ同様の操作である。 今回は,2つの実習を行う.
授業開始までに次のことを行っておく.
mkdir ~/public_html/softwareDevelなど.
プログラムをおくディレクトリの下にdata用のディレクトリを用意し、そこの解凍したファイルを置く。
教室のWindowsを使っている場合は,Uドライブの"U:\public_html"に,たとえば"softwareDevel\data"というフォルダを作って,そこにzipファイルを展開する.
ファイルを扱う基本は
$handle = fopen("ファイル名", "モード");
$buffer = fgets($handle);
fclose($handle)
参照ページ:「初心者用PHP入門」のファイルの読み書きの章
(ファイルを扱う関数の詳細は,マニュアルのファイルシステムを参照する.)
例: ファイルを開き,1行ごと読込み,そのまま画面に出力する
<?php $handle = @fopen("data/sample1.csv", "r"); if ($handle) { while (!feof($handle)) { $buffer = fgets($handle); echo $buffer; } fclose($handle); } ?>
ここで"@"は「エラー制御演算子」で,右側の式(この場合はfopenの実行)でエラーが生じた場合,エラーメッセージが左辺に代入されることなく無視するものである.(別のグローバル変数に代入さる.)
次のようなCSV形式のファイルを読込んで,表形式で表示すると共に列の平均値を表示するようにしなさい.(下記データを新たなcsvファイルとして格納し利用してもよいし,前準備で作成したcsvファイルを使ってもよい) [締切 11/14]
平均値の出力は後回しにし、まずはデータをtable表示するプログラム作りに取り組むこと。
平均値を表示する進んだ例1 空欄を含む列の処理が正しくできていない。
$str_array = explode(",",$buffer);
for($i=0; $i< count($str_array); $i++) { $str_array[$i]を用いた処理 }
ディレクトリ操作関数(マニュアル参照)を用いる. opendir関数の例2を参照を参照し,次の演習を行う.
ディレクトリにおかれたファイル名を決め打ちでプログラム内に指定するので はなく,プログラムの実行段階で,存在するファイル(の一覧)を取得し,順 次開いてデータを読み込む手法を理解することにねらいがある.このような方 式であれば,CSVファイルを追加,変更するだけでページが書き換えられること になる.したがって,プログラムを書く人と,データを更 新する人の作業分担が可能になる.
下準備で置いたディレクトリにあるファイルを拾い出し,それらを演習1と同じような表形式で表示するhtmlで表示する書きなさい.ただし,ファイルごとにファイル名を明示する形式にすること. [締切 11/21]
できた人は、次章を飛ばして課題6(関数の定義と利用)を行って下さい。課題4と関連 が深い内容です。
<?php $dir = "./"; // 既知のディレクトリをオープンし、その内容を読み込みます。 if (is_dir($dir)) { /* $dirがディレクトリであればtrue */ $dh = opendir($dir); /* ディレクトリがあればハンドラ(ポインタ)を$dhに代入,なければfalse */ if ($dh != false) { while (1) { /* $dhから一つの項目(ファイルやディレクトリ)を読み出す */ $file = readdir($dh); if($file === false) break; // 開けなければ,次へ echo "filename: $file : filetype: " . filetype($dir . $file) . "\n"; } closedir($dh); } } ?>
while( ) { if(!preg_match('/\.csv$/',$file)) continue; echo $file; }preg_match('/文字列パターン/', 文字列変数)は,正規表現関数 の一つで,文字列変数があるパターンにマッチしているかどうかを確かめ る関数である.正規表現は少々難しいが勉強してみると楽しいはずである. (授業では簡単に触れるだけにするが,次節に解説を書く.余裕のある人は先に 進んで正規表現を勉強して欲し い.奥が深いからである.)
上記の例は,末尾が".csv"でなければ,下の実行文をスキップし,次の while制御に移ることを指示するものである.
2. 上記で選択できたファイル名のファイルを順に開き,課題4のような処理を行う.
正規表現については,http://www.ne.jp/asahi/futohen/sankaku/h083.htmを参照して欲しい.(そのほかにもWeb上にはたくさんの解説がある.)
以下は,授業では行いません.興味があれば自習してください.
Linuxには,テキストから正規表現で目的の文字列を抜き出すツールとしてgrepというのが備わっている.それを用いて練習してみよう.grepの拡張版egrepを使用する.
less /usr/share/dict/words(lessはテキストファイルの内容をみるツールで,上下のカーソルキーなどで位置移動できる.終了にはqをおす.)
grep "active" /usr/share/dict/words
のようにすると"active"という文字を含む単語が抜き出される.
grep "r.*active" /usr/dict/words
のようにする.ドット"."は「任意の一文字」を表し,アスタリスク"
*
"は直前の文字の0個以上の連続を表す.このような特別な意味を表す文字を **メタキャラクタ**という.
以下にgrepで用いられる正規表現を列記する. (一般に,正規表現というと,下記の太字の項(連結,閉包,選択)を表す.)
文字列$ | 行末にある「文字列」 |
c | cという文字そのもの.cはメタキャラクタではないこと. |
cd | 文字cとdがこの順で現れる.( 連結: concatenation ) |
\c | cという文字そのものcがメタキャラクタであれば,メタキャラクタとしての性質を打ち消す. |
[abc] | a,b,c文字のどれか.[ ] のなかに入っているものの1文字 |
[^abc] | a,b,c以外の文字のどれか.[ ] のなかに入っているものの以外の文字 |
. | 任意の一文字 |
X* | Xの0個以上のならび (繰り返し(閉包): closure) |
X\{m\} | Xのm回の繰り返し.ただし,egrepでは,バックスラッシュなしで,X{m}とする. |
\(文字列\) | 「文字列」と同じだが,マッチした部分をおぼえ,あとで「¥数字」でそれを参照できる.egrepではバックスラッシュなしの( )とする. |
^文字列 | 行の先頭にある「文字列」 |
これに加えて,egrepでは
文字列1|文字列2 |
文字列1または文字列2 (選択: union) |
a+ | aの1個以上の連続 |
(文字列) | 文字列と同じ (くくり出しのかっこ) たとえば(ab)*はabの0個以上の繰り返し |
パターン | "egrep パターン /usr/share/dict/words"としたときに選びだされる単語 |
---|---|
(tion|tive)$ | tionあるいはtiveで終わる単語 |
..........$ | ちょうど10文字の単語 |
^(.)(.).\2\1$ | 5文字の回文 |
/usr/share/dict/wordsを材料にして,次のものを調べてみよう.各種フィルタ(tr, wc, sortなど)を組み合わせて行うこと.
1. 配列の内容がどのようになっているか確かめるには、
<code>print_r という関数を使う。(プログラムのテストに便利) 課題3のプログラムのなかで、次のような命令を入れてみると、 $str_array
の内容をみることができる。試してみよう。
print_r($str_array);
2. 「発展」の意味は必ずしも高度であることを意味しない.授業時間の都合で,正式課題として時間をかけないものも含む.