プログラムで特定のワードをマッチさせて、文章を書き込む方法を教えてください

このQ&Aのポイント
  • プログラムを使って特定のワードがマッチした場合に文章を書き込む方法を教えてください。
  • プログラムの中で@delという配列に格納されたワードと、$FORM{'sub_product'}に入っているワードを比較し、マッチした場合には$inという文章をlog.csvに書き込みたいです。
  • 初心者ですが、上記の要件を満たすプログラムの作成方法を教えていただけないでしょうか?
回答を見る
  • ベストアンサー

どうやればいいのかわかりません><;

あるプログラムを完成させたいんですが、 以下の部分がうまくいきません。 foreach $del_word ( @del){ if ( "$FORM{'sub_product'}" =~ /$del_word/){ open(IN, ">>./csv/log.csv") or printErrorPage("エラー"); eval{ flock (FILE, 2) }; seek(IN, 0, 2); print IN "$in"; close(IN); { exit; } } } 簡単に説明しますと、 @delは1行に1単語(例えば「時計」など)ずつ約10行ほど入力したdel.csvファイルの内容が入っています。 ちなみにそこの部分は open(OUT, "./csv/del.dat") or printErrorPage("エラー"); eval{ flock (OUT, 1) }; @del = <OUT>; close OUT; です。 そして、どういった作業をしたいかというと、 この$FORM{'sub_product'}に入っているワードに@delに収納されているワードがひとつでもマッチする場合、 $inという文章をlog.csvに書き込むというプログラムです;; 初心者なのですが、どなたかアドバイスいただけたらと思います!!どうぞ宜しくお願いしますーっm(_)m

  • CGI
  • 回答数5
  • ありがとう数3

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

  • ベストアンサー
  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.5

>以下ではなぜか動作しません><; 多分、 @delと@nodelと@limdel の配列のサイズが違うのに $nで参照しているからじゃないですかね~ 同じサイズの配列で、同じ位置にあるもので判定するならいいかもしれないですけど。 いちいち、配列でループして調べるのがいいと思いますけど 例えば、あんまり能率を気にしないのだったら $retdel =grep "$FORM{'sub_product'}" =~ $_/x, @del; $retnodel =grep "$FORM{'sub_product'}" =~ $_/x, @nodel; $retlimdel=grep "$FORM{'sub_product'}" =~ $_/x, @limdel; とかしておいて if($retdel > 0 && $retnodel==0 && $retlimdel > 0){ #@delでマッチしてかつ、@nodelにマッチしなくてかつ、@limdelにマッチ } とかできるかも(未確認)

その他の回答 (4)

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.4

>if ( "$FORM{'sub_product'}" =~ /$del_word/x){ >で空白を無視する場合は、配列の中のワードは全てくっついてしまうのですか?? $del_word は、foreach で取り出した、1つですから、くっついてしまうということはありません。

qaz911
質問者

お礼

で・・・できましたーっ!!! BLUEさんほんとありがとうございますっ!!! あの~・・もう1つ聞きたいところがあるんですけど~・・ よろしいでしょうか><;すみません。;; 「3つのcsvファイルから読み込んだ配列@delと@nodelとlimdelの中身がそれぞれ$FORM{'sub_product'}とマッチするかどうか、@delの中身$del_wordにマッチしてかつ、$nodelにマッチしなくてかつ、$limdelにマッチするもののみをcsvに$inとして書き込む」というプログラムなのですが、以下ではなぜか動作しません><; なにかいい方法はありませんでしょうか? 宜しくお願いします~~><; #データ判別・書き込み foreach $del_word ( @del){ #削除判別ワードでマッチング if ( "$FORM{'sub_product'}" =~ /$del_word/x){ #削除除外ワードでマッチング if ( "$FORM{'sub_product'}" =~ /$nodel[$n]/x){ last; #削除限定ワードでマッチング }elsif( "$FORM{'sub_product'}" =~ /$limdel[$n]/x){ #削除チェックリストオープン open(IN, ">>log.csv") or printErrorPage("エラー"); eval{ flock (FILE, 2) }; seek(IN, 0, 2); #書き込みデータ作成 $in = "$FORM{'title'},"."$FORM{'sub_condition'},"."$FORM{'sub_product'},"."$FORM{'sub_subproduct'},"."$FORM{'sub_exc'},"."$del_word"; print IN "$in"; close(IN); last; } } ++$n; }

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.3

>@delだけを表示させてみると、 >csvファイルに入ってるワードが半角スペースで区切られて表示されてるんです;; print @del; というように表示を試しているということですか? foreach $x (@del){ print ":$x:\n"; } で、コロンの前にスペースがあったり、改行されたりするなら、 本当にスペースがあるのでしょうね もし、そうだとしたら、書き出しの側に問題があるような気がしますが、 パターンマッチングする前に $del_word =~ s/\s+//g; として空白を削除してやるか if ( "$FORM{'sub_product'}" =~ /$del_word/x){ として空白を無視するオプションをつければ良いと思います。

qaz911
質問者

お礼

早速の返信ありがとうございます!! >print @del; >というように表示を試しているということですか? そのように表示してみたところ、やはり半角スペースが入ってました;; if ( "$FORM{'sub_product'}" =~ /$del_word/x){ で空白を無視する場合は、配列の中のワードは全てくっついてしまうのですか?? 半角スペースをカンマに変えれば、ちゃんとした配列としてみなされるのでしょうか? そういった場合、どういう風に作ればいいのでしょうか? たくさん質問かいてすみません><; BLUEさんほんと詳しいので、もしよろしければまた回答おねがいしますーっ!!

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.2

@delの中身に改行が残ってるということだったら chomp @del; を foreach $del_word ( @del){ の前に入れてやればいいかと思います。

qaz911
質問者

お礼

返信ありがとうございます!! やってみたのですが、なんだかうまく機能してないみたいなんです;; @delだけを表示させてみると、 csvファイルに入ってるワードが半角スペースで区切られて表示されてるんです;; なんででしょうか><;

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.1

どういう風にうまくいかないのでしょうか? seek ?

qaz911
質問者

補足

あ、説明不足でした><; 早速みていただいてありがとうございますーっ!! えっとですね、 @delの中身なんですが、 csvファイルで1つのセルごとに右にワードをいれていくと、 中身がカンマで区切られるのですが、 自分は改行して文字を入力しているので、 中身が半角スペースで区切られてるみたいなのです。。。 だからか、なぜだかうまく$del_wordに@delの中身が入らないみたいなんですよね;;; 説明下手でごめんなさいーっ><; またなにかございましたらすぐ補足いたしますっ! どうぞよろしくおねがいしますm(_)m

関連するQ&A

  • ログの一部を消す Perl

    ログの一部を消すPerlを考えています。 ここではソースを短くするために、ログの一部を消し去って ログファイルに上書きするデータは $deta だけだとすると open F, '+<a.log'; flock F,2; $deta = <F>;//実際はここでもっと処理 truncate F,0; seek F,0,0; print F $deta; close F; と、 open IN, 'a.log'; flock IN,2; open OUT, '>a.log'; flock OUT,2; $deta = <IN>;//実際はここでもっと処理 print OUT $deta; close OUT; close IN; の2つを考えました。 上のように 読み込み と 書き込み を同時にやった方がいいのか 下のように分けてやった方がいいのか教えてください。 ロックは flock を使って、普通レベルのロックが できるぐらいでいいと思っているんだけど、 この flock の書き方でおかしいところがあれば 教えてください。

    • ベストアンサー
    • CGI
  • 掲示板を全削除機能にしたいのですが

    現在使っている掲示板は投稿を個別に削除は出来るのですが、一括削除は出来ません。一括削除だけしたいのですが、一括削除できる定型文のようなものはあるのでしょうか?よろしくお願いします。(Iモード用BBSです。本CGIスクリプトのメンテ部分です。) sub mainte { my($del) = (0); if($form{'pass'} ne $mainte_pass){ &error ("bad password."); } $out_val{'pass'} = $form{'pass'}; if($form{'id'}){ # delete if(&lock($log_file, 5)){ open (IN, "< $log_file") or &error ("can't open $log_file to read. $!"); open (OUT, "> $log_file.$$") or &error ("can't open $log_file.$$ to write $!"); $del = 0; while(<IN>){ if(/^$form{'id'}\t/){ $del = 1; next; }else{ print OUT $_; } } close IN; close OUT; if($del){ rename $log_file, "$log_file.bak"; rename "$log_file.$$", $log_file; chmod 0666, $log_file; $msg = qq|$form{'id'}番の投稿を削除しました。<BR>\n <A href="$out_val{'cgi_name'}">戻る</A>|; &error($msg); }else{ unlink "$log_file.$$"; $msg = qq|$form{'id'}番の投稿は存在しません。<BR>\n <A href="$out_val{'cgi_name'}">戻る</A>|; &error($msg); } } }else{ if(&lock($log_file, 5)){ open (IN, "< $log_file") or &error ("can't open $log_file to read. $!"); while(<IN>){ ($id, $time, $name, undef, $title ) = split "\t"; $out_val{'del_list'} .= qq|$id, $time, $name, $title<BR>\n|; } &page_out($mainte_page); } } unlock($log_file); return 1; }

    • ベストアンサー
    • CGI
  • 全行読み込むには

    open( IN, "pass.dat" ) or die "Can't open pass.dat: $!"; $f_data = <IN>; close( IN ) or die "Can't close pass.dat: $!"; $f_data1 = $f_data; $f_data2 = $f_data; $f_data1 =~ s/<br>//g; $f_data2 =~ s/\S//g; open( OUT, ">log.dat" ) or die "Can't open log.dat: $!"; select OUT; print "$f_data1"; print "$f_data2"; select STDOUT; close( OUT ) or die "Can't close word.js: $!"; 上記スクリプトでは、pass.datの一行目しか読み込まれません。全行を読み込むためにはどのように書き換えればいいのでしょうか?宜しくお願いします。

    • ベストアンサー
    • Perl
  • 行頭に変なスペースが…

    入力したデータをログファイルの一番上に入れたいために以下のようにしました。 open(FH2,"***.log"); flock(FH2,2); @files = <FH2>; flock(FH2,8); close FH2; open(FH,">***.log"); @filew = "user=$FORM{'name'}<>TIME=$FORM{'TIME'}\n@files"; print FH @filew; close(FH); こうするとなぜかログファイルの2行目以降の頭にスペースが1文字分入ります。 2個目のログファイルオープンの3行目 print FH @filew; のスペースが原因かと思い、 print FH@filew; としてみましたが、やっぱりスペースが入りました。 このスペースを入らないようにするにはどうしたらいいでしょうか?

    • ベストアンサー
    • Perl
  • ログファイルを削除するcgiプログラム

    ログファイルを削除するcgiプログラム -------------------- $GYOUSUU = $FORM{'GYOUSUU'}; #--- ログファイルオープン open(FH,"***.log"); flock(FH,2); @FILES = <FH>; flock(FH,8); close FH; undef $FILES[$GYOUSUU]; open (FH2,">***.log"); @filew = "@FILES\n"; print FH2@filew; close(FH2); -------------------- となっているのですが、修正後にログファイルの行の頭に、半角スペースが入ってしまいます。 どこを修正すればいいのでしょうか?

    • ベストアンサー
    • Perl
  • flockについて

    http://www.freespace.jp/phpstudy.php4 のサイト様を拝見したり、フリーで配布されているスクリプトを見ると、書き込むファイルに対して、 $fp = fopen('bbs.log', 'r+'); flock($fp, LOCK_EX); … とやっていると思うのですが、perl記述のcgiで掲示板を作成したときは、書き込むファイルとは別にロック用のファイルを用意し、(perl記述です) open(LOCK,"+<$lockfile"); flock(LOCK,2); open(IN,"$logfile"); .... close(IN,"$logfile"); open(OUT,"$logfile"); .... close(OUT,">$logfile"); としていました。(書き込むファイルが2つあったのでこのような方法をとってました) そこでphpでも同じ方法は使えるのでしょうか? $fp = fopen('bbs.log', 'r+'); flock($fp, LOCK_EX); … の方法を使おうと思っていたのですが、最初にログファイルを読み込むとき、 file("bbs.log"); という風にしているので、flockに記述すべきファイルハンドルが見当たりません。仮に取得できたとしても、file();の仕様からして内部にcloseが入ってそうなので、flockできたとしてもcloseで無効になってしまわないかが心配です。なのでこの場合はやはり別にログファイルを用意しないとできないということでしょうか。

    • ベストアンサー
    • PHP
  • ファイルの最後の行から表示させる(最新情報を5回分だけ表示)

    ファイルの最後に1行追加し、6行以上になるとファイルの先頭を1行削除。 表示は最後の行から行うスクリプトを作りたいのです。 新しい情報を5回分だけ表示する様にしたかったのですが、余りにも力技なのでもう少しスマートにやる方法を教えてもらえませんか? ----sort.txt---- 1a 2b 3c 4d ---------------- #!/usr/bin/perl $fname = "sort.txt"; print "Content-type: text/html;\n\n"; $aaa="5e"; open(OUT, ">>$fname"); flock(OUT, LOCK_EX); print OUT "$aaa\n"; flock(OUT, LOCK_NB); close(OUT); open(IN, "$fname"); $cnt = "0"; while($line = <IN>){ $a[$cnt] = "$line"; $cnt++; } close(IN); if($cnt > 5){ open(OUT, ">$fname"); flock(OUT, LOCK_EX); $cnt = "0"; while($cnt < 6){ if($cnt > 0){ print OUT "$a[$cnt]"; } $cnt++; } flock(OUT, LOCK_NB); close(OUT); } $cnt = "0"; open(OUT, "$fname"); @buff = <OUT>; close(OUT); foreach $line ( reverse @buff ){ $cnt++; print "$line<br>\n"; } exit();

    • ベストアンサー
    • Perl
  • 受信データの分割

    @atai = split(/&/,$buffer); foreach $atais(@atai){ ($key, $value) = split(/=/, $atais); $FORM{$key}=$value; } 多分上記のようなことをすればできるのだと思うのですが、 自分の力でコードをかきたくて、1行ずつかいてみました。 #ファイルオープン open FILE,"<log.log"; flock(FILE,2); @log_data=<FILE>; flock(FILE,8); close FILE; foreach(@log_data){ (@log) = split(/=/,$_); } foreach(@log){ ($log_data) = split(/&/,$_); } foreach($log_data){ ($key,$value) = split(/=/,$_); } $FORM{$key}=$value; このようにかいてみたのですがうまくいきません。 よろしくお願いします。

    • ベストアンサー
    • CGI
  • 掲示板の文字色指定について

    はじめまして。私は学生で超のつく初心者なのですが、課題で掲示板を作っています。 基本的な表示はなんとかうまくいったのですが、よくある、文字色を選択して好きな色で文章(コメント)を表示させるプログラムがわかりません。 if文を使うパターンではなく、色の情報を書き込み、ファイルからデータを読み込むやり方でできるらしいのですが、どうやって書いたらよいのでしょうか・・・。 ちなみにhtml表示部分に、色の指定はしてあり、赤、青、緑、黄色でvalueはred,blue,green,yellowにしています。 下に書き込みと読み込みの部分を乗せたのですがどう入れたらいいでしょうか。 本当に初心者だし分かっていないので説明もわかりにくくてすいません。もしどなたか分かる方いたらよろしくお願いします。 #------------------------------------------------------------ # 登録データ書き込み処理 #------------------------------------------------------------ sub writeData() { # $DATAFILEをオープンする open(FILE, ">> $DATAFILE") or die("error:$DATAFILE open error!"); eval{ flock(FILE, 2); }; $timestr = &getTimestr(); $in{'comment'} =~ s/\n/<br>/g; print FILE "$in{'namae'},$in{'dai'},$in{'comment'},$timestr,"; close(FILE); } #------------------------------------------------------------ # 登録データ読込み処理 #------------------------------------------------------------ sub readData() { # $DATAFILEをオープンする open(FILE, "< $DATAFILE"); eval{ flock(FILE, 2); }; while(<FILE>){ chomp; $line[$cnt++] = $_; } close(FILE); }

    • ベストアンサー
    • CGI
  • csvデータの開始行と最終行を全体の4分の1で区切り処理をしたい

    csvデータの開始行と最終行を全体の4分の1で区切り処理をしたい csvデータの開始行と最終行を全体の4分の1で区切り処理をしたいと思ってます。 csvファイルは20万件あります。4分の1なので1~50000件となります。 今回は50001~100000件までを行いたいのですが、先日教えていただいたwhile($lines = <IN>) ですと、最初から1件ずつ最終行まで処理をしてしまいます。 (ここから) open(OUT,">$csv"); open(IN,"$data") || &error(" $data を読み込みopen出来ません"); while($lines = <IN>) { ($seq1,$categ,$password,$imail,$cont) = split("\,", $lines); $cont .= " "; $data = "$seq1,$cont,1\n"; print OUT "$data"; $data = ""; } close IN; close OUT; (ここまで) 今回は20万件ですが、毎回このデータ量は月次ごとに変わります。 while周辺をいじるような気がしていますがどのようになるのかがわからなかったので質問いたしました。 お手数かけます。 よろしくお願いいたします。

    • ベストアンサー
    • Perl

専門家に質問してみよう