• ベストアンサー

正規表現でのエラー

検索システムを作ろうと思っています。テキストファイル(このソースではgreetings.txtです。)の中にある文章をキーボード入力で1文字でもヒットすれば抜き取って表示させたいのですが、以下のソースをコマンドプロンプトで実験したところ「Q、Y,S,M、と記号」で検索すると全ての文章がヒットしてしまいます。他の文字では問題無くヒットするのですが…。perlを始めてばかりでまだまだわからないことだらけです。いちおう本やネットで検索したんですがさっぱりわかりません。どなたかどうかお力を貸していただけませんか? #!C:\Perl\bin\perl $kensaku = <>; $ans = eval $kensaku; open(IN, "greetings.txt"); while ($line = <IN>){ if($line =~ /$ans/i){ print "$line"; } }

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

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

Perlはそのままでは日本語(をあらわす文字コード)を理解しません。 そのため、 >for %i in (オ ツ イ シ) do echo %i | hexdump 00000000: 83 49 20 0A .I . 00000000: 83 63 20 0A .c . 00000000: 83 43 20 0A .C . 00000000: 83 56 20 0A .V . オ、ツ、イ、シのそれぞれにI, c, C, Vを見つけてしまいます。 この問題はPerlに日本語文字コードを理解させればいいので、 たとえば以下のようにスクリプトを書き換えます。 $kensaku = <>; $ans = $kensaku; chomp $ans; $ans = Encode::decode('sjis', $ans); open(IN, '<:encoding(sjis)', "greetings.txt") or die "can't open data file\n"; while ($line = <IN>){ chomp $line; if($line =~ /$ans/i){ $line = Encode::encode('sjis', $line); print $line, "\n"; } } use encoding プラグマを使うという方法もありますが、 問題を起こしやすいのでお勧めしません。

tokko64
質問者

補足

上記のスクリプトで試してみましたが、 Undefined subroutine &Encode::decode called at Z:\a.pl line 7, <> line 1. というエラーが出てスクリプトがうまく動きませんでした。sakusaker7さんは、うまく動くことができたのでしょうか?encodeというものが調べていくうちに多少はわかったのですが、どういうふうにモジュールをつけたら良いのかわかりません…。引き続きご回答をいただきたいと思います。

すると、全ての回答が全文表示されます。

その他の回答 (6)

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

んーエラーが再現しません。 スクリプトは use Encode; $kensaku = <>; $ans = $kensaku; chomp $ans; $ans = Encode::decode('sjis', $ans); open(IN, '<:encoding(sjis)', "greetings.txt") or die "can't open data file \n"; while ($line = <IN>){ chomp $line; if($line =~ /$ans/i){ $line = Encode::encode('sjis', $line); print $line, "\n"; } } __END__ $kensaku = <>; #$ans = eval $kensaku; $ans = $kensaku; open(IN, "greetings.txt"); while ($line = <IN>){ if($line =~ /$ans/i){ print "$line"; } } で、greetings.txtは以下の通り 湘南乃風 KREVA monkey Majik ACIDMAN 175R ケツメイシ レミオロメン 大塚愛 以下実行例です。 D:\work\script\perl>perl find.pl 愛 大塚愛 D:\work\script\perl>perl find.pl ケ ケツメイシ D:\work\script\perl>perl find.pl 南 湘南乃風 perl -w スクリプト名 のように -w オプションを指定して実行してみてください。 何か警告は出てきませんか?

tokko64
質問者

お礼

すみません。スクリプトにちょっと余計なものを打ち込んでしまったみたいです…。コピペしてみたら普通に動作しました^^;申し訳ないです。お手数おかけしてすみませんでした。何回もご親切に教えてくださって本当に感謝しています。また何かあればここに来ようと思います。

すると、全ての回答が全文表示されます。
  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.6

すみません。スクリプトをコピーするときに一行抜けてしまったようです。 スクリプトの先頭に use Encode; という行を加えてください。 これでコンパイルが通るようになるはずです。

tokko64
質問者

お礼

ありがとうございました。無事コンパイルも通り、正常にプログラムを動作させることができました!また何かわからないことがあれば質問させていただきます。本当にありがとうございました!

tokko64
質問者

補足

お礼を投稿しておいて申し訳ないのですが、今度は日本語のデータが検索できなくなってしまいました。ファイルオープンに使っている「greetings.txt」には、 湘南乃風 KREVA monkey Majik ACIDMAN 175R ケツメイシ レミオロメン 大塚愛 という日本語を含んだ文字列が含まれているのですが、これを検索しようとすると、 F:\perl>perl sisaku.pl 南 Quantifier follows nothing in regex; marked by <-- HERE in m/? <-- HERE ?/ at si saku.pl line 14, <IN> line 1. F:\perl>perl sisaku.pl 愛 Quantifier follows nothing in regex; marked by <-- HERE in m/? <-- HERE ?/ at si saku.pl line 14, <IN> line 1. F:\perl>perl sisaku.pl ケ Quantifier follows nothing in regex; marked by <-- HERE in m/? <-- HERE P/ at si saku.pl line 14, <IN> line 1. といったようなエラーが出てきます。これを改善することは可能でしょうか?何度もすみません。お手数おかけしますがお願いします。

すると、全ての回答が全文表示されます。
  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.4

ああ、大文字じゃなくてq,y,s,m は小文字なんですね。 わかりました。 これは $ans = eval $kensaku; でeval してるからです(なんのため?) q, y, s, m はそれぞれ特別な意味を持つものなので、evalすると 消えてなくなるようです。 s は s///, y は y/// qは シングルクォートの代わりの記号の指定 mは m/// の指定に使われますから。 :\work\script\perl>perl -de 42 oading DB routines from perl5db.pl version 1.28 ditor support available. nter h or `h h' for help, or `perldoc perldebug' for more help. ain::(-e:1): 42 DB<1> print eval "q" DB<2> print eval "@" DB<3> print eval "Q" Q だから、 DB<4> print eval "tr" DB<5> これも消えます。

tokko64
質問者

お礼

なるほど、そういうことだったんですか。どうもうまくいかないので本を読みあさっていた所、evalを使っている例文を見つけまして、適当にくっつけたところあんな感じで半分成功の半分失敗状態になってしまいました…。いや、意味がわかっていないのでは完全に失敗ですね; わかりやすいご説明どうもありがとうございました!大変勉強になりました。ですが、この後また問題が起こりまして…。詳しいことは、guci-okさんへの補足に書いてあります。できればもう少し力を貸していただけませんか?お願いします。

すると、全ての回答が全文表示されます。
  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.3

うまくいかないという具体例を挙げてもらえませんか? スクリプトと補足されたgreetings.txt をそのままコピペして試してみましたが D:\work\script\perl>perl err.pl g Good morning good bye good night D:\work\script\perl>perl err.pl Q D:\work\script\perl>perl err.pl a thank you スクリプトにちょっとまずいところはありますが、問題点が明らかに なっていないのでとりあえずは指摘しないでおきます。

tokko64
質問者

補足

私の場合では、Qと打ったところ、「greetings.txt」の全文が表示されてしまいました。具体的に申しますと F:\perl>perl sisaku.pl q Good morning hello good bye thank you good night F:\perl>perl sisaku.pl F:\perl>perl sisaku.pl y Good morning hello good bye thank you good night F:\perl>perl sisaku.pl s Good morning hello good bye thank you good night F:\perl>perl sisaku.pl m Good morning hello good bye thank you good night F:\perl>perl sisaku.pl @ Good morning hello good bye thank you good night のように、「Q、Y、S、M」と「記号」で入力すると、「greetings.txt」の中に「Q」は一つも入ってないはずなのに、「greetings.txt」の全文が表示されてしまいます。 ちなみに他の英数字で入力すると、ちゃんと期待通りの結果が返ってきます。 F:\perl>perl sisaku.pl g Good morning good bye good night F:\perl>perl sisaku.pl a thank you F:\perl>perl sisaku.pl h hello thank you good night sakusaker7さんは、見たところ「Q」で入力しても何も表示されずうまくいっているみたいですね。なぜでしょうか?perlのバージョンの問題でしょうか?ちなみに使っているperlのバージョンは5.8です。

すると、全ての回答が全文表示されます。
  • guci-ok
  • ベストアンサー率33% (49/146)
回答No.2

キーボード入力で指定するのは、正規表現ですか、マッチさせたいテキストですか?  後者ならquotemeta関数を通します。 $kensaku = <>; chomp $kensaku; $ans = quotemeta($kensaku);

tokko64
質問者

お礼

guci-okさんの言われたとおりにやってみたらちゃんと期待通りの結果が得られました!quotemeta関数を調べてみたところ、どうやら文字列中の記号が正規表現のメタ文字として扱われるのを防ぐものらしいですね。だから記号等で検索した場合、全文の内容を表示されてしまったんですね。以外とあっさりした解決で以外でした^^; 質問の内容に不足していた部分があるにもかかわらず教えてくださり、本当にどうもありがとうございました!また機会があれば質問させていただきたいと思います。

tokko64
質問者

補足

すみません、さっきのでいちおう解決はしたんですが、日本語の文章も検索させて見ようと思い、「greetings.txt」の内容を変更し、自分の知っている歌手などの名前を適当に入れてみました。内容はこうです。 greetings.txt 湘南乃風 KREVA monkey Majik ACIDMAN 175R ケツメイシ レミオロメン 大塚愛 これで動かしてみると「i」,「c」,「v」で入力して検索をかけたときになぜかカタカナのデータまで表示されてしまいます。実際の表示では、 F:\perl>perl sisaku.pl i monkey Majik ACIDMAN レミオロメン F:\perl>perl sisaku.pl c ACIDMAN ケツメイシ F:\perl>perl sisaku.pl v KREVA ケツメイシ こんな感じです。調べてみたところ、「i」は「オ」に、「c」は「ツ」と「イ」に、「v」は「シ」にヒットしてしまうようです。どうしてこのようなことが起こるのでしょうか?また、この問題を解決するにはどうしたらいいのでしょうか?一度解決させていただいたのに、何度も質問をして申し訳ありませんが教えていただけないでしょうか。お願いします。

すると、全ての回答が全文表示されます。
  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

greetings.txt の中身もわからんし「実際にはどのようにキーボードから入力したか」もわからんのだから, かなり回答しずらいんだけど... ちなみに, なんで eval してるの?

tokko64
質問者

補足

greetings.txtの内容は Good morning hello good bye thank you good night といったものです。例えばここから「g」とキーボードから入力することで「Good morning」「good bye」「good night」が表示されるようにしたいのです。「a」と入力すれば「thank you」が表示されたり。試行錯誤したのですが、ちゃんとした結果が得られません。引き続き回答お願いします。

すると、全ての回答が全文表示されます。

関連するQ&A