• ベストアンサー

以下の関数の解説お願いします。

Perl初心者のため、stdio.plにある この関数のやっていることがよく分からず困っています。 sub searchString #($str, $key, $mhmode, $lc, $z2h, $k2h, $igmark) { local($str, $key, $mhmode, $lc, $z2h, $k2h, $igmark) = @_; local($once, $from, $to); #static $key2, $key3; return 0 if ($str eq "" || $key eq ""); if ($key eq $key2) { $key = $key3; $once = 1; } else { $key2 = $key; } if ($jcode'version) { if ($k2h) { $from = 'アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワヲンガギグゲゴザジズゼゾダヂヅデドバビブベボパピプペポゐゑァィゥェォャュョッ'; $to = 'あいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめもやゆよらりるれろわをんがぎぐげござじずぜぞだぢづでどばびぶべぼぱぴぷぺぽヰヱぁぃぅぇぉゃゅょっ'; } if ($z2h) { $from .= '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+-=_|*!?”#$¥%&@:;'; $to .= '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+-=_|*!?"#$\%&@:;'; } if ($igmark) { $from .= '-ー・/_ '; $to .= '------'; } if ($from) { &jcode'tr(*str, $from, $to); &jcode'tr(*key, $from, $to) if (!$once); $str =~ tr/-_\///d; $key =~ tr/-_\///d; } } if ($lc) { $str =~ tr/A-Z/a-z/; $key =~ tr/A-Z/a-z/ if (!$once); } $key3 = $key; if ($mhmode == 5 || $mhmode =~ /^BOOLEAN$/i || $mhmode =~ /^BLN$/i) { local($i) = 0; local(@str, $eval); $key =~ s/ +AND +/ & /gi; $key =~ s/ *NOT +/ ! /gi; $key =~ s/ +OR +/ | /gi; $key =~ s/\( +/(/g; $key =~ s/ +\)/)/g; foreach (split /( & | \| )/, $key) { $str[$i] .= $_; $i ++ unless ($_ eq ' & ' || $_ eq ' | ') } for ($i = 0; $i <= $#str; $i ++) { local($option, $open, $close, $find, $not, $key); $key = $str[$i]; if ($str[$i] =~ /^( & | \| )/) { $option = substr $key, 0, 3; $key = substr $key, 3; } $open = $1 if ($key =~ /^(\(+)/g); $close = $1 if ($key =~ /(\)+)$/g); $key =~ s/\(|\)//g; if ($key =~ /^ *! +/) { $key =~ s/^ *! +//g; $not = 1; } $find = index($str, $key) >= 0 ? 1 : 0; $find = $find ? 0 : 1 if ($not); $eval .= "$option$open$find$close"; } $eval =~ s/ & /*/g; $eval =~ s/ \| /+/g; return (eval $eval >= 1) ? 1 : 0; } elsif ($mhmode == 4 || $mhmode =~ /^NOR$/i) { foreach (split / +/, $key) { return 0 if (index($str, $_) >= 0); } return 1; } elsif ($mhmode == 3 || $mhmode =~ /^EOR$/i) { local($flag) = 0; foreach (split / +/, $key) { if (index($str, $_) >= 0) { return 0 if ($flag); $flag = 1; } } return $flag ? 1 : 0; } elsif ($mhmode == 2 || $mhmode =~ /^OR$/i) { foreach (split / +/, $key) { return 1 if (index($str, $_) >= 0); } return 0; } elsif ($mhmode == 1 || $mhmode =~ /^NAND$/i) { foreach (split / +/, $key) { return 1 if (index($str, $_) == -1); } return 0; } else { foreach (split / +/, $key) { return 0 if (index($str, $_) == -1); } return 1; } } これを呼び出しているのが、別ファイル内の以下の部分です。 foreach(@datafile){ if($datafile[0] eq $_){ next; } # 1行目は項目名なので next if($param{'query_word'}){ unless(stdio::searchString($_, $param{'query_word'}, $param{'query_search_type'}, 1, 1, 1, 1)){ next; } } push(@search_file,$_); } datafileは 名前,住所,電話番号, 吉田,東京都渋谷区,03xxxxxxxx, といったデータファイルです。 よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • TYWalker
  • ベストアンサー率42% (281/661)
回答No.1

うわあ~長いプログラムですね~ まず呼び出している方から。 インデントを全角空白で加えて、ちょっと整形してみます。 foreach(@datafile){  if($datafile[0] eq $_){   next;  } # 1行目は項目名なので next  if($param{'query_word'}){   unless(stdio::searchString($_, $param{'query_word'}, $param{'query_search_type'}, 1, 1, 1, 1)){    next;   }  }  push(@search_file,$_); } ということは、@datafile という配列の他に、$param{'query_word'}, $param{'query_search_type'} というハッシュ要素(おそらく CGI フォームのデータ?)を受け取って処理していますね。 foreach(@datafile){  ... } は、配列 @datafile を1要素ずつ $_ に入れながら周回し、@datafile が尽きたら終了するループです。  if($datafile[0] eq $_){   next;  } # 1行目は項目名なので next というのは、ちょっとトリッキーですが、$datafile[0](@datafile 配列の1要素目)が $_ に等しかったら next で次の周回に飛ばすという意味ですね。 名前,住所,電話番号, というのは見出し行だから飛ばしているわけですね。 次に、  if($param{'query_word'}){   ...  } というのは、$param{'query_word'} が何か中身があれば、... の部分を実行すると言うわけですね。 $param{'query_word'} というのは %param というハッシュを 'query_word' というキーで検索したときの値ですが、これがどうやってセットされたどういう値なのか上の情報からではわかりませんね。   unless(stdio::searchString($_, $param{'query_word'}, $param{'query_search_type'}, 1, 1, 1, 1)){    next;   } は、stdio.pl の searchString という関数に、  ・$_ <== 現在注目している @datafile の各データ。たとえば「吉田,東京都渋谷区,03xxxxxxxx,」  ・$param{'query_word'} <== %param というハッシュを 'query_word' というキーで検索した値。このハッシュが作られている方法は不明  ・$param{'query_search_type'} <== 同じく %param というハッシュを 'query_search_type' というキーで検索した値  ・あと「1」が4つ という引数を渡して、その文字列がもし「偽」(ゼロ、空文字列、undef のいずれか、実のない値)であれば next で次の周回に向かいます。 で、最後に、  push(@search_file,$_); というのは、$_(現在注目している @datafile の各データ。たとえば「吉田,東京都渋谷区,03xxxxxxxx,」)を @search_file という配列の末尾に追加しています。 ということで、このメインプログラムは全体として、  ・@datafile 配列の2行目以降を  ・searchString という関数に、$param{'query_word'}、$param{'query_search_type'} という値を渡したもので検査し  ・合格したものを @search_file という配列に貯める ということをやっているみたいですね。 shift @datafile; @search_file = grep {stdio::searchString($_, $param{'query_word'}, $param{'query_search_type'}, 1, 1, 1, 1}, @datafile; という2行で書いても同じことです。 stdio というのは Standard Input Output で、標準入出力に何かするんでしょう。 searchString という名前なんだから、何らかの文字列を検索するんでしょうね。 ★ ここで、ちょっと考えを変え、stdio、searchString で Google 検索してみます。 (最初から気づくべきだった) http://www.google.co.jp/search?rls=ig&hl=ja&source=hp&q=searchString+stdio&lr=&rlz=1W1GGLL_ja&aq=f&oq= とすると、 http://winofsql.jp/perl/stdio/stdio.pdf にめちゃめちゃバッチリ stdio.pl の解説があるじゃないですか!(PDFですが) 21ページ目に searchString の説明があります。 いろいろ面白いことができるみたいですよ!

その他の回答 (1)

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.2

ところがぎっちょん (古いなぁ), searchString の 3引数目のいくつかと 4引数目以降は undocumented feature なんですよ>#1. そもそも引数の名前が謎. mhmode って何の略だよ. 4引数目以降を簡単にいうと ・4つ目: 大文字と小文字を同じとみなすかどうか ・5つ目: 英数字などで ASCII と複数バイト文字を同じとみなすかどうか ・6つ目: かたかなとひらがなを同じとみなすかどうか ・7つ目: 音引きなどを同じとみなすかどうか です. しかし.... 引数の渡し方とか, もうちょっと何とかならんものかなぁ.

関連するQ&A