- ベストアンサー
配列を対象にして正規表現の置換、うまくいきません
正規表現の置換ができませんのでお教え下さい。 @list= ('aaa', 'bbb', 'ccc'); $sentence = 'rrr bbb dddd eee aaa rrrr bbbb aaa'; foreach (@list) { $sentence =~ s/$_/あああ/g; } print $sentence; どうしてもエラーになります。 そこで \をつけて、$sentence =~ s/\$_/あああ/g; などとやってみても置換されません。 どこが間違えているのでしょうか。よろしくお願いします。
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
既にお気付きかもしれませんが、 今度のエラーは、変なところで区切られて処理されたために発生しています。 「/」に注目して考えてみると分かると思いますよ。 </a>を<\/a>と記述している理由とは・・・ 私もときどきやってしまうミスですけどね。
その他の回答 (4)
- feininger
- ベストアンサー率41% (74/180)
うーん、惜しい! 適当ですけど、こんなの↓はどうですか? @list= ('aaa','???'); $sentence = 'aaa bbb ??? ddd ???'; foreach (@list) { s/([\+\*\.\?\^\$\[\-\]\|\(\)\\])/\\$1/g; #エスケープ $sentence =~ s/($_)/<a href="$1">$1<\/a>/g; } print $sentence;
お礼
ああ、このエスケープ式は文字列表示の際に特定文字列の色やゴシックを指定する置換書法として以前にここで教えていただいたものです。 今これをまた使うわけですね。私のほうの正規表現知識がそれほど進んでいないので恐縮ですが、教えて下さい。 $sentence =~ s/($_)/<a href="http://localhost/dic/GermJ.cgi?Tomo=$_ target=_parent">$1<\/a>/g; ってやってもリンクが張れません。と言うか-wスイッチをつけてコンパイルすると、Syntacs Error に成ります。 引き続きどうかよろしくお願いします。
えとですね(^_^; foreach 内で $_ に格納される各値は、メタ文字の前に \ を添えてあげなければいけません。 でなければ、$_ 内の文字を正規表現文字列であるとして解析しようとしてしまいます。
お礼
はい、それはエスケープする、ということですね。目下その点をめぐって悪戦苦闘しているところです。 つまり: foreach (@list) { $yakugo =~ s/\$_/\<a href=\"http:\/\/localhost\/dic\/GermJ\.cgi\?Tomo=\$_\" target=\"_parent\"\>\$_\<\/a\>/g; } アンカーを張ることが目的なのですが、こんなに\をつけてしまった。。結局、これではアンカーが実現しませんでした。何度かうまくいったこともあるのですが。。。 どうぞ、よろしくお教え下さい。
- natsuki_tk
- ベストアンサー率35% (99/279)
-wスイッチをつけてエラー原因を確認すれば 何のエラーなのかすぐわかるように思うのですが・・。 現在与えられている情報から類推するのは無理があります。 (というより全て絞りきれません。) 文字列として使えないものがあるかどうかという点ですが、 例えば下記の???が仮にあったとしたら、エラーを起こすはずです。 (つまり、ありますという答えになります。)
お礼
やはり???が原因であったようです。これで @list にエラー原因があったことがわかりました。 もう一つの変数$sentence も簡略化しすぎておりました。実は次のように置換するつもりなのですが、エスケープをきちんとする知識が私にはまだありません。見よう見まねで次のようにして試しているのですが、エラーにはなりませんが、表示として思った通りの結果が得られません。済みませんが、こちらのほうも御教示下さいませんでしょうか $sentence =~ s/$_/\<a href\=\"http\:\/\/localhost\/dic\/GermJ.cgi\?Tomo\=$_" target\=\"_parent\"\>$_\<\/a\>/g;
コピー&ペーストして実行してみましたが、特に問題なく動いてるようですが……。 それとも、「思ったとおりに動かない」ということなのでしょうか?
お礼
お答えをいただきありがとうございました。 たしかに簡略化して@list=('aaa'...) としたこの例では動くのですが、実際の@list の内容は-archie -beduerftig -ern -fall -fluegler -flueglig -geil -getreu -halben -halber -haltig -henkelig -leibig -maeulig -maxe -pflichtig -phor -schwemme -spaltig -stimmig -strophig -taeglich -traechtig ..faltig ..id ..massen ??? a cappella a conto a piacere a prim の具合に5万語あります。それが原因なのかも知れませんが、エラーになります。改行テキストを@listに格納しているのですが、文字列として正規表現に受け入れられないものでもあるのでしょうか。。。。
お礼
毎度毎度お世話になりっぱなしで。。。(^_^;) 「/」がとぎれの原因ですよね。そこで: $sentence =~ s/($_)/<a href="http:\/\/localhost\dic\/GermJ\.cgi\?Tomo=$_ target=_parent">$1<\/a>/g; って、やってみました。アンカーはやはり実現していません。楽しい正規表現ですが、苦しいですねえ、わかんないときは。。。
補足
補足します。その後、アンカーが実現しました。GermJ.cgi というプログラムに引数を渡したかったので、 $yakugo =~ s/($_)/<a href="http:\/\/localhost\/dic\/GermJ.cgi?Tomo=$1" target="_parent">$1<\/a>/g; としていたところが、GermJ.cgi の大文字の「G」が引っかかっていて思うような置換結果が得られていなかったことを突きとめました。(なぜなのでしょうか??) あとまだエスケープが完全でないため、アンカーが単語の途中に張られたり、置換の副作用で一部不必要な置換結果が出てしまいますが、これで基本はできました。 ありがとうございました。 それにしても、あのエスケープ行は、いまだによく理解していません。あのー、その解説をお願いしてもよろしいでしょうか? つまり、これ↓ですが:(^_^;) s/([\+\*\.\?\^\$\[\-\]\|\(\)\\])/\\$1/g; #エスケープ