last-modified: 25th/June/'01;
since: 1st/June/2001;
前節では極基本的なハッシュの使い方を見てきました。本節ではファイル内の情報をハッシュとして処理するサンプルを作ってみます。
具体的には、「名前」と「 URL 」を列記したファイルに対して名前による検索をします。
データファイルは links.dat
とし、書式は「名前 = URL
」とします。
links.dat
>>
NEXTindex = http://www.sugai.f2s.com/ Yahoo! Japan = http://www.yahoo.co.jp/ Google = http://www.google.com/ goo = http://www.goo.ne.jp/ |
スクリプトの流れは、ファイルをハンドル LINKS
で読み込み、等号 「 =
」を区切り文字として、前後をハッシュ %links
のキーと値に分けて読み込みます。
ファイル情報を全てハッシュ %links
に読み込んでから、「名前」をキーボード入力してURLの候補を検索します。
links.pl
>>
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: | #!/usr/bin/perl #上の行では、 Perl のパスを記述してください。 open(LINKS, './links.dat') || die "links.dat: $!"; while(chomp($line = <LINKS>)) { ($key, $value) = split(/\s*=\s*/, $line); $links{$key} = $value; } close(LINKS); @key_list = keys(%links); $counts = @key_list; while(1) { print "サイト名をどうぞ (press x to end):"; chomp($sitename = <STDIN>); exit if($sitename eq x); $miss = 0; foreach $key (@key_list){ if($key =~ /$sitename/i) { print " $key; $links{$key}","\n"; } else { $miss++; } } if($miss == $counts){ print "No such link.","\n"; print "Try Again: "; } } exit; |
line 1-2:
コメント行で、 perl
の所在地です。
line 4-9
ファイル links.dat
を開いて、ファイルハンドル LINKS
を結びつける。
line 6:
函数 split
でファイルハンドル LINKS
から読み込んだ行を区切り文字で切断してリストに代入する。
split
の基本書式:
リスト・配列 = split(/正規表現/, スカラー文字列);
上のスクリプトの例の場合は、/正規表現/
が /\s*=\s*/
になっている。 \s
は「空白類文字」を表し、*
はゼロ回以上の繰り返しを表すメタ文字。全体で、「 =
」の前後に空白がゼロ回以上存在する文字列にマッチする。
例えば、文字列が "Yahoo! Japan = http://www.yahoo.co.jp
" の場合、 " =
" が区切り文字になり、リスト (Yahoo, http://www.yahoo.co.jp)
に変換される。
このリストが、 ($key, $value)
に代入されるから、結果的に、次のようになる。
$key = Yahoo! Japan; $value = http://www.yahoo.co.jp;
このキーと値を用いて 7 行目ではハッシュ %links
を生成している。
12 行目ではキーの個数を変数 $counts
に代入している。スカラーコンテキストでは、配列は要素の個数を返すことに注意。
line 11:
keys
は、ハッシュの引数を配列として読み込む函数。今の場合は、ハッシュ %links
の全てのキーを配列 @key_list
に代入している。
line 14-30:
ここは繰り返しで、キーボード入力の文字列にマッチする「キー」に対応する「値」を出力する。
Perl では UNIX の小規模データベースを使えます。これは dbm データベースと呼ばれています。
ODBM
: UNIX 標準装備NDBM
: 比較的新しく UNIX に標準装備SDBM
: perl
に添付GDBM
: GNU 版高機能 dbmこれらのデータベースを利用するためには、 opne
, close
の代わりに、 tie
, untie
を利用します。本稿では説明しませんので、 perl
に添付されているマニュアルをご覧ください。
上のスクリプトでは、ハッシュのキーを配列として抜き出す函数 keys
を利用しましたが、値を抜き出す values
、キーと値の組を順番に返す each
に関して紹介します。
以下では、ハッシュの例として、次のものを考えます:
%sites = ('Yahoo! JAPAN' => 'http://www.yahoo.co.jp/', 'Google' => 'http://www.google.com/', 'SUGAI,M.' => 'http://www.sugai.f2s.com/', 'goo' => 'http://www.goo.ne.jp/')
keys
はハッシュのキーを配列として返します。 values
は値を配列として返します。
@array = keys(%sites); foreach(@array){ #@array の各要素は標準変数 $_ に代入 print "$_; url= $sites{$_}\n"; }
この例では、一行目を削除して、 foreach
ループの条件式を次のように書き換えても結構です:
foreach(keys %sites){ #keys %sites の値(キー)が標準変数に代入される
ここで注しなければいけないことは、 keys
函数の戻り値の順番はランダムだということです。 values
函数と併用して、次のように書いたとすると、キーと値が一致しなくなります:
@array1 = keys(%sites); @array2 = values(%sites); foreach(@array1){ print $_: $array2{$.-1}; }
キーや値を、何らかの順番で並べたいときには、 sort
函数を用います。
foreach(sort values %sites){ print "$.: $_\n"; }
each
函数は、繰り返しの中で用いられ、「キーと値」の組を一つずつ返します。ハッシュから配列を生成しないので、実行環境のリソースをいたずらに浪費しないというメリットがあります(要素数が数千、数万以上に上るデータベースを参照する場合を考えてください)。
while(($key,$value) = each(%sites)){ print "name = $key, url = $value \n"; }Copyright: SUGAI, Manabu. Since: 2001