• ベストアンサー

配列を対象にして正規表現の置換、うまくいきません

正規表現の置換ができませんのでお教え下さい。 @list= ('aaa', 'bbb', 'ccc'); $sentence = 'rrr bbb dddd eee aaa rrrr bbbb aaa'; foreach (@list) { $sentence =~ s/$_/あああ/g; } print $sentence; どうしてもエラーになります。 そこで \をつけて、$sentence =~ s/\$_/あああ/g; などとやってみても置換されません。 どこが間違えているのでしょうか。よろしくお願いします。

  • Perl
  • 回答数5
  • ありがとう数5

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

  • ベストアンサー
  • feininger
  • ベストアンサー率41% (74/180)
回答No.5

既にお気付きかもしれませんが、 今度のエラーは、変なところで区切られて処理されたために発生しています。 「/」に注目して考えてみると分かると思いますよ。 </a>を<\/a>と記述している理由とは・・・ 私もときどきやってしまうミスですけどね。

tonka729
質問者

お礼

毎度毎度お世話になりっぱなしで。。。(^_^;) 「/」がとぎれの原因ですよね。そこで: $sentence =~ s/($_)/<a href="http:\/\/localhost\dic\/GermJ\.cgi\?Tomo=$_ target=_parent">$1<\/a>/g; って、やってみました。アンカーはやはり実現していません。楽しい正規表現ですが、苦しいですねえ、わかんないときは。。。

tonka729
質問者

補足

補足します。その後、アンカーが実現しました。GermJ.cgi というプログラムに引数を渡したかったので、 $yakugo =~ s/($_)/<a href="http:\/\/localhost\/dic\/GermJ.cgi?Tomo=$1" target="_parent">$1<\/a>/g; としていたところが、GermJ.cgi の大文字の「G」が引っかかっていて思うような置換結果が得られていなかったことを突きとめました。(なぜなのでしょうか??)  あとまだエスケープが完全でないため、アンカーが単語の途中に張られたり、置換の副作用で一部不必要な置換結果が出てしまいますが、これで基本はできました。  ありがとうございました。 それにしても、あのエスケープ行は、いまだによく理解していません。あのー、その解説をお願いしてもよろしいでしょうか? つまり、これ↓ですが:(^_^;) s/([\+\*\.\?\^\$\[\-\]\|\(\)\\])/\\$1/g; #エスケープ

その他の回答 (4)

  • feininger
  • ベストアンサー率41% (74/180)
回答No.4

うーん、惜しい! 適当ですけど、こんなの↓はどうですか? @list= ('aaa','???'); $sentence = 'aaa bbb ??? ddd ???'; foreach (@list) { s/([\+\*\.\?\^\$\[\-\]\|\(\)\\])/\\$1/g; #エスケープ $sentence =~ s/($_)/<a href="$1">$1<\/a>/g; } print $sentence;

tonka729
質問者

お礼

ああ、このエスケープ式は文字列表示の際に特定文字列の色やゴシックを指定する置換書法として以前にここで教えていただいたものです。  今これをまた使うわけですね。私のほうの正規表現知識がそれほど進んでいないので恐縮ですが、教えて下さい。 $sentence =~ s/($_)/<a href="http://localhost/dic/GermJ.cgi?Tomo=$_ target=_parent">$1<\/a>/g; ってやってもリンクが張れません。と言うか-wスイッチをつけてコンパイルすると、Syntacs Error に成ります。  引き続きどうかよろしくお願いします。

noname#25358
noname#25358
回答No.3

 えとですね(^_^;  foreach 内で $_ に格納される各値は、メタ文字の前に \ を添えてあげなければいけません。  でなければ、$_ 内の文字を正規表現文字列であるとして解析しようとしてしまいます。

tonka729
質問者

お礼

はい、それはエスケープする、ということですね。目下その点をめぐって悪戦苦闘しているところです。 つまり: foreach (@list) { $yakugo =~ s/\$_/\<a href=\"http:\/\/localhost\/dic\/GermJ\.cgi\?Tomo=\$_\" target=\"_parent\"\>\$_\<\/a\>/g; } アンカーを張ることが目的なのですが、こんなに\をつけてしまった。。結局、これではアンカーが実現しませんでした。何度かうまくいったこともあるのですが。。。 どうぞ、よろしくお教え下さい。

回答No.2

-wスイッチをつけてエラー原因を確認すれば 何のエラーなのかすぐわかるように思うのですが・・。 現在与えられている情報から類推するのは無理があります。 (というより全て絞りきれません。) 文字列として使えないものがあるかどうかという点ですが、 例えば下記の???が仮にあったとしたら、エラーを起こすはずです。 (つまり、ありますという答えになります。)

tonka729
質問者

お礼

やはり???が原因であったようです。これで @list にエラー原因があったことがわかりました。 もう一つの変数$sentence も簡略化しすぎておりました。実は次のように置換するつもりなのですが、エスケープをきちんとする知識が私にはまだありません。見よう見まねで次のようにして試しているのですが、エラーにはなりませんが、表示として思った通りの結果が得られません。済みませんが、こちらのほうも御教示下さいませんでしょうか $sentence =~ s/$_/\<a href\=\"http\:\/\/localhost\/dic\/GermJ.cgi\?Tomo\=$_" target\=\"_parent\"\>$_\<\/a\>/g;

noname#25358
noname#25358
回答No.1

 コピー&ペーストして実行してみましたが、特に問題なく動いてるようですが……。  それとも、「思ったとおりに動かない」ということなのでしょうか?

tonka729
質問者

お礼

お答えをいただきありがとうございました。 たしかに簡略化して@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に格納しているのですが、文字列として正規表現に受け入れられないものでもあるのでしょうか。。。。

関連するQ&A

  • Perlの正規表現について

    Perlの正規表現について質問です. ■質問 aaa bbb aaa bbb ccc "ddd" aaa bbb ccc "ddd eee" aaa bbb ccc ddd eee "fff ggg hhh iii" というような,文字列が書かれているファイルがあるとします. ※ダブルクォーテーションが無い行もあります. ※ダブルクォーテーション内のスペースの数は,行によってそれぞれ異なります. これを,ダブルクォーテーションの中にあるスペースだけ アンダーバーに置換する場合の正規表現を教えて下さい. つまり,下記の出力にしたいです. aaa bbb aaa bbb ccc "ddd" aaa bbb ccc "ddd_eee" aaa bbb ccc ddd eee "fff_ggg_hhh_iii" ■条件 ※ちょっと古いPerlでも動くよう,ゼロ幅肯定/否定後読((?<),(!<))は使わないでください. ※単に実現するだけなら, # cat inputfile | print -pe 'sub f(){}(shift;s/ /_/;return $_;); s/(\".*\")/&f($1)/e;' みたいな感じで置換できそうですが,「正規表現だけで簡単に書けるかどうか」が知りたいのです(正規表現だけで実現出来る場合,そのアルゴリズムを知りたいです).そのため,関数と/eオプションは使わないでください.

    • ベストアンサー
    • Perl
  • VBAの正規表現

    VBAで正規表現による置換をしたいです。 以下のような行が複数あります。 1 aaa bbb ccc ddd 2 aaa bbb ccc ddd 3 aaa bbb ccce ddd 4 aaa bbb eccc ddd ccc の部分のみ置換したいです。 dim hensuu as string dim replace as string replace = eee hensuu = ccc (省略) strPattern = "(\s*)" & hensuu & "(\s+)" rep = RegExpObj.Replace(buf, "\1" & replace & "\2") 行数1,2 のみを置換したのですが、4も置換されてしまいます。 (\s*) の "*" が良くないのは理解していますが、"+" にしてもうまくいきません。 どなたかどのようにしたら1,2のみ置換できるようになるかをご教授お願いできませんでしょうか よろしくお願いいたします。

  • 正規表現について

    正規表現で、最初に出てきた条件に合うものだけマッチさせて置換したく、それ以降に条件に合うものがあってもマッチさせたくないのですが、どうすればいいでしょうか? 現在、オプションはつけてないのですが、最後にマッチしたものがとりだされてしまいます。 ---------------------------------------- s/aaa(.*)ccc/$1/; ・・・・・正規表現 ---------------------------- aaabbbccc : : aaadddccc : aaaeeeccc ---------- だと、eeeに置換されるのですが、bbbに置換したいです。 よろしくお願いします。

    • ベストアンサー
    • Perl
  • 正規表現で一つ目の区切り文字で区切りたいのですが・・・

    aaa/bbb/ccc/ddd aaa/bbb/ccc/ddd/eee aaa/ccc/ddd $a=~/(.*)\/(.*)/; $1はそれぞれ aaa/bbb/ccc aaa/bbb/ccc/ddd aaa/ccc と成ってしまいます。 このように 「最後の/」で分けられてしまいます。 一つ目の/で分けるにはどうしたらよいでしょうか。

    • ベストアンサー
    • Perl
  • 秀丸の正規表現を使って置換

    三番目の引数が0かNULL、nullならば、以下のように秀丸で置換したいのですが、やり方がわかりません。正規表現を使って置換したいです。 abcmethod(aaa, bbb, 0, ccc)やabcmethod(aaa, bbb, null, ccc)    ↓↓↓↓↓↓ abcmethod(aaa, bbb, ccc) aaa,bbb,cccは任意の文字半角アルファベットや数値です。 abcmethod(.+,.+,.+,.+)で、検索できますが、置換の仕方がわかりません。 どうぞよろしくお願いします。

  • 文章中のファイルリンクを置換したい

    文章をjavascriptで読み込み、 以下のような文章のなかに埋まっているファイルリンクの文字を 置換してあげたいのですが、正規表現で表現しきれないでしょうか? ■例: ---以下文章---- あああああ いいいいい \\AAA\BBB\CCC ううううううう \\CCC\DDD\EEE えええええ --------------- とあった時に、下記のようにしたいと考えています。 --------------- あああああ いいいいい <a href="file:////AAA/BBB/CCC">\\AAA\BBB\CCC</a> ううううううう <a href="file:////DDD/EEE/FFF">\\DDD\EEE\FFF</a> えええええ --------------- 今考えている限りだとは\\までを含む文章まではマッチさせて、 リプレースできるのですが、 文章の中の\を/に置き換える方法が思いつきません。 ■私の頭の限界の正規表現だけだと下記までしか思いつきませんでした。 str.replace ( /(\\\\[^ \s\:\*\?\"\<\>\|\#\{\}\%\&\~]+)/gi , <a href=\"file:\/\/$&\">$&<\/a>)> どなたか思いつくことありましたらお知恵をかしていただけないでしょうか。

  • 2回以上繰り返される文字列の削除について

    以下の文字列(置換前)で、-aaa について複数存在しているので、 最初の -aaa を残して残りの -aaa をすべて削除したいと考えています。 1回の正規表現+置換で行いたいのですが、どのようにいすればよいでしょうか? 【置換前】 -bbb -aaa -ccc -aaa -ddd -eee -aaa -fff 【置換後】 -bbb -aaa -ccc -ddd -eee -fff ちなみに、複数回の正規表現+置換を使ってよい場合は、 while (m/( -aaa.*) -aaa/) { s/( -aaa.*) -aaa/$1/; } でできると考えています。(動作確認まではしていないので間違ってるかも)

    • ベストアンサー
    • Perl
  • perlでの正規表現について教えてください。

    たとえば、 $A = 'aaa/bbb/ccc/ddd/eee/fff/ggg' というものがあったときにperlの正規表現でddd/のすぐ後の部分を抜き取って違う変数に入れたいのですが、それを正規表現で切り取りたいのですが、どうしたらいいかわからないです。 初歩的な質問ですが、お答えいただければ幸いです。 よろしくお願いします。

  • 正規表現

    正規表現 a=/home/aaa/bbb/ccc/ddd.abc echo ${a%.abc}実行したら /home/aaa/bbb/ccc/ddd が表示されますが、 home/aaa/bbb/ccc/ddd に表示したいですがうまくいきません。 ネットで正規表現さがしてみたけど理解できませんでした。 教えていただきたいです。なお 説明文も簡単に記入していただいたら幸いです。

  • ○○個目と●●個目の××を置換したいのですが...

    例えば, aaa\n bbb\n ccc\n ddd\n eee\n ... となっているテキストファイル(\nは改行)の,3n個目(n=1,2,3,...)の\n(つまり3,6,9,...個目の\n)を\tに置換したいのですが,そのようなツールはありますでしょうか? (あるいはそのような正規表現を教えていただければと思います.perlでやろうとしたのですが,不慣れなためできませんでしたので...) よろしくお願い致します.

専門家に質問してみよう