• ベストアンサー

Perl 文字列を配列に直す方法

こんにちは。 今Perlをやっているのですが、変わった文字列を配列に上手く入れて、配列を操作するところで行き詰っています。 例として、 windows95 windows98 windows2000 windowsXP windowsVista このように並んだものを、配列に入れて処理を行いたいです。 ただコレを$wordsに入れて$words = @wordsとしても、その後の処理に詰まってしまいます。 その後の処理コード自体は使えるものなので、配列の入れ方に問題があると思っているのですが、私の中で答えを導くことはまだ出来ていません(汗 解決方法または良いやり方があれば、是非教えていただきたいです。 宜しくお願いします。

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

  • ベストアンサー
  • sample_
  • ベストアンサー率76% (20/26)
回答No.6

最終的にあるデータを読み込んでカウントできればよいという 認識でもよいですか?? という前提をしてみて下記のようなやり方はいかがでしょうか~? データ自体は別ファイルにあるとする ファイル名:log.txt データは下記10個入っているとする。 windows95 windowsXP windows98 windows98 windowsXP windows2000 windows98 windowsXP windowsVista windowsXP でカウントする側のコードが ----------------------------------------------- use strict; use warnings; open (my $fh, "<", "./log.txt") or die "$!"; flock($fh, 2); chomp(my @list = <$fh>); close $fh; my %count; foreach my $str (@list){ $count{$str}++; } chomp(my $word = <STDIN>); if($count{$word}){ print $word, "の検索回数は、", $count{$word}, "回です\n"; }else{ print "。・゜・(ノД`)・゜・。そんなのないよ…\n"; } ----------------------------------------------- これをプロンプトで実行して windowsXPと入力すると windowsXPの検索回数は、4回です となります。 実際には、web上で入力してもらたキーワードに対するデータを表示することになるでしょうから、 chomp(my $word = <STDIN>); の代わりに差し替えて使ってもらえばよいかと思いますがいかがでしょうか?

noname#97332
質問者

お礼

sample_さん 返答ありがとうございます. 頂いたコードは非常に有益でした! ありがとうございます(*^_^*) しかしながら,私の既存のプログラムの文字列が,動的に形成(コードにより出力)されており,textファイルに上手く格納されませんでした. if($word) { $word =~ tr/+/ /; $word =~ s/%([0-9a-fA-F][0-9a-fA-F])/chr(hex($1))/eg; eval { $word = Jcode::convert(\$word, "euc"); }; $word =~ s/&/&amp;/g; $word =~ s/</&lt;/g; $word =~ s/>/&gt;/g; if($FORM{'option'} eq "word1") { ++$freg{$word}; } 上記の処理でリファラーURLを元の語群に変換し,表示. elsif($FORM{'option'} eq "word2") { my $word2; $word =~ s/\x81\x40/ /g; foreach $word2 (split(/\s+/, $word)) { if($word2) { ++$freg{$word2}; } } } 上記の処理で,語群を単語単位に直しております. こうして形成された文字列を編集できるようになれば,教えてくださった処理も出来るのですが・・・. アドバイスありがとうございました. 助かります!

その他の回答 (5)

  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.5

補足しているようでされてないのでなんとも答えづらいです。 いきなりまったく別のスクリプトだけみせられてこのようにと云われても、 実際に現在質問者さんの一番の障害となっているものを取り除くための情報がありません。 推測できなかないですが。 > 簡単な元データ例と、集計結果の例をだして何をしたいかの > 具体的なサンプルを示してもらえませんか?

noname#97332
質問者

お礼

sakusaker7さん 返答ありがとうございます.毎回言葉足らずですみません. 現在検索ワードの羅列をしているコードのうち,リファラーを抽出し,表示している$word1が, if($word) { $word =~ tr/+/ /; $word =~ s/%([0-9a-fA-F][0-9a-fA-F])/chr(hex($1))/eg; eval { $word = Jcode::convert(\$word, "euc"); }; $word =~ s/&/&amp;/g; $word =~ s/</&lt;/g; $word =~ s/>/&gt;/g; if($FORM{'option'} eq "word1") { ++$freg{$word}; } 上記の通りになっております. 次に,そのリファラーを分割した$word2が elsif($FORM{'option'} eq "word2") { my $word2; $word =~ s/\x81\x40/ /g; foreach $word2 (split(/\s+/, $word)) { if($word2) { ++$freg{$word2}; } } } こちらです. 今回,その単語のランキングを作るために$word3を設けて表示させたいのですが,プログラムにより動的に動いている$word各種をどう処理すればランキングとして動いてくれるのか分かりません. 発想としては,いったん配列@wordsに格納し,キーワードを設けて配列の中を検索し抽出,抽出したものをカウントして降順に並べれば良いかなと思いました. しかし,$word2の段階で処理した語群が上手く配列@wordsに入っていないせいか,その後のコードが動きません. 語をカウントしたり,検索・抽出するコードは別のファイルにて動作確認済みなので,問題は配列に上手く入っていないか,その後の処理コードの形式が適切ではないかの2つだと思います. 私は前者だと思うのですが・・・. もし宜しければ,考え方の間違いやコードのミス,方法などありましたら,お教えください. 度々すみません. よろしくお願いします.

回答No.4

ANo.2です。 > @word2 = split(/\n/, $words); > というコードなのですが,$wordsが既に処理されている値の(何らか > の処理をされて,上記のような値になっている)場合も適用されます > か? 適用されます。(単に改行コードで文字列を分割しているだけです) > 私が実行してみたところ,格納までは出来たのですが, > その後の処理(文字の抽出,カウントなど)が表示されませんでした. どのようにされているのかが見当がつきませんので 問題が無い範囲でソースを開示いただけませんか?

noname#97332
質問者

お礼

Tanigucchiさん 返答ありがとうございます. 集計したログのうち,検索ワードを扱うためのコードが以下です. if($word) { $word =~ tr/+/ /; $word =~ s/%([0-9a-fA-F][0-9a-fA-F])/chr(hex($1))/eg; eval { $word = Jcode::convert(\$word, "euc"); }; $word =~ s/&/&amp;/g; $word =~ s/</&lt;/g; $word =~ s/>/&gt;/g; if($FORM{'option'} eq "word1") { ++$freg{$word}; } elsif($FORM{'option'} eq "word2") { my $word2; $word =~ s/\x81\x40/ /g; foreach $word2 (split(/\s+/, $word)) { if($word2) { ++$freg{$word2}; } } } elsif($FORM{'option'} eq "word3") { my $word3; @words = split(/\n/, $word3); { #とりあえず表示してみる print @words; } } } word2までの処理は出来ていて,今回新たにword3で検索ワードのランキングを扱おうと思っております. その部分がまだ機能していないので,どうしようかと思ってます. 度々説明不足すみません.お手数おかけします. よろしくお願いします.

  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.3

ひょっとして >具体的に言いますと,アクセス解析において検索ワードの集計をしたいのですが,$wordsで表示されている > > windows95 > windows98 > windows2000 > windowsXP > windowsVista > > を,配列@wordsに代入し,集計を行おうと思っています. @words に格納されたこれらのOSがログの中でどのくらい現れるのかを 「集計」したいとかいう話でしょうか? >集計にはgrep関数を用いようと思っているのですが,配列が > @words=('windows95','windows98','windows2000',・・・) > のような形式ではないため,思うように動きません. grep で集計というのもよくわかりませんし、配列が現状どうなっていて どうだめなのかの情報がまるでありません。 どのように動くのが、「思ったように」なのかも不明です。 簡単な元データ例と、集計結果の例をだして何をしたいかの 具体的なサンプルを示してもらえませんか?

noname#97332
質問者

お礼

sakusaker7さん 返答ありがとうございます. 私の使っているアクセス解析に似ているソースは http://www.kantansakusei.com/analyzer/pre.cgi?file=3 こちらです. これで集計したログで,検索ワードを調べていこうと思っています. 調べる方法として,grep関数を使って配列から検索し,別の関数を使ってワード数を集計しようかなと思っております. また分からないところがございましたら,指摘お願いします. すみません.

回答No.2

$wordsに格納される値ですが、以下のようなイメージでしょうか? #データ格納 $words =<<END_OF_DATA; windows95 windows98 windows2000 windowsXP windowsVista END_OF_DATA #改行コードで分割して配列に格納 @word2 = split(/\n/, $words); #配列から取り出して印刷してみる foreach (@word2) { print $_ . "\n";}

noname#97332
質問者

お礼

Tanigucchiさん 返答ありがとうございます. @word2 = split(/\n/, $words); というコードなのですが,$wordsが既に処理されている値の(何らかの処理をされて,上記のような値になっている)場合も適用されますか? 私が実行してみたところ,格納までは出来たのですが,その後の処理(文字の抽出,カウントなど)が表示されませんでした. 度々申し訳ありません. よろしくお願いします.

回答No.1

具体的にコードを提示できませんか? >ただコレを$wordsに入れて$words = @wordsとしても の部分が何をしたいのかがわかりません。 配列への代入は @words = ("windows95","windows98", …); とか $word[0] = "windows95"; とか push(@words, "windows95"); で実現できます。

noname#97332
質問者

お礼

Tanigucchiさん 返答ありがとうございます. 具体的に言いますと,アクセス解析において検索ワードの集計をしたいのですが,$wordsで表示されている windows95 windows98 windows2000 windowsXP windowsVista を,配列@wordsに代入し,集計を行おうと思っています. 集計にはgrep関数を用いようと思っているのですが,配列が @words=('windows95','windows98','windows2000',・・・) のような形式ではないため,思うように動きません. そこで配列に問題があると考え,上記の質問を致しました. 言葉足らずですみません.

専門家に質問してみよう