Perlで変数を使用した置換ができない

このQ&Aのポイント
  • Perlのスクリプトで変数を使用した置換がうまくいかない場合、正しい展開方法を確認する必要があります。
  • 変数展開がうまくいかない場合、変数が正しく設定されているか、正しい置換方法を使用しているかを確認しましょう。
  • Perlの置換処理では、正規表現を使用して置換することが一般的です。正しい正規表現のパターンを設定することで、変数の展開が正しく行われます。
回答を見る
  • ベストアンサー

Perlで変数を使用した置換ができない

ファイル内の「1 2 3 4 5」などの数字の箇所を、「1回 2回 3回 4回 5回」のように、「回」をつけた形に変えることを考えています。 以下のようなスクリプトを書きましたが、うまくいきません。 # 「$search_replace」の参照先のテキストファイルの内容 (\d) タブ記号 $1回 ・ ・ EOF # 問題のスクリプト(一部) chomp($search_replace); (my $search, my $replace) = split(/\t/, $search_replace); $string[$i+1] =~ s/$search/$replace/g; #ここが問題と思われる箇所 ほしい結果は右のとおり。「1回 2回 3回 4回 5回」 現実の結果は右のとおり。「$1回 $1回 $1回 $1回 $1回」 置換文字列の$1の部分がうまく展開(?)できないようです。 どうすればよいか、ご教示ください。

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

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

  • ベストアンサー
  • kumoz
  • ベストアンサー率64% (120/185)
回答No.5

正規表現の置換部はダブルクォート文字列と同様に評価されるので、次の2つの文は同じように機能します。質問のケースでは、変数を2重に置き換えなければならないので、明示的にダブルクォートが必要になります。 $string[$i+1] =~ s/$search/$1回/g; $string[$i+1] =~ s/$search/"$1回"/eg;

cat-rice
質問者

お礼

なるほど、よくわかりました。 ありがとうございました。

その他の回答 (4)

  • ORUKA1951
  • ベストアンサー率45% (5062/11036)
回答No.4

>ただ、質問に対する回答としてはズレがあるのではないかと思います。  と言われても、 >>ファイル内の「1 2 3 4 5」などの数字の箇所を、「1回 2回 3回 4回 5回」のように、「回」をつけた形に変えることを考えています。  だったらいちいち配列やハッシュに入れる必要はないかと・・  もうすこし具体的にオリジナルデータ中に、ぽつんと「1\t2\t3\t4\t5」とあるのか、詳しい説明がないと・・ 例 1_挨拶とオリエンテーション 2_カリキュラムの紹介、HTMLとは ・・・とか

cat-rice
質問者

お礼

質問に答えるだけの能力がないことをわざわざお知らせいただき、ありがとうございました。 今後ともよろしくお願いします。

  • kumoz
  • ベストアンサー率64% (120/185)
回答No.3

次のようにすれば、置き換えられるかも? $string[$i+1] =~ s/$search/qq(\"$replace\")/eeg;

cat-rice
質問者

お礼

ありがとうございました。無事、動きました。 もしよろしければ、補足入力もご覧いただければと思います。

cat-rice
質問者

補足

ありがとうございました。置換文字列を「式」とみなす(evaluation)ことを2回繰り返しているのですね。ただ、ここでの$replaceが、どのようにして最終的な展開形となるのか、うまく自分の頭のなかで説明できません。qq( ) と、" " がどのように機能している(「"」がエスケープされている理由も含めて)のでしょうか。

  • ORUKA1951
  • ベストアンサー率45% (5062/11036)
回答No.2

(my $search, my $replace) は2値の配列なのに、元データは?? chomp($search_replace); my $separator = "\t"; my $newSeparator = "回"; $search_replace =~s/$separator/$newSeparator/g; print $search_replace,$newSeparator,"\n"; とか chomp($search_replace); my $separator = "\t"; my $newSeparator = "回"; my @data = split(/$separator/, $search_replace); while(<@data>){ print $_,$newSeparator; } print "\n";

cat-rice
質問者

お礼

ありがとうございました。ただ、質問に対する回答としてはズレがあるのではないかと思います。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

えばる

cat-rice
質問者

お礼

ありがとうございました。鈍感な私では、それがevaluationのことだとはわかりませんでした。

関連するQ&A

  • VBSでのhtmlタグ要素名の置換

    ' VBSでのhtmlタグ要素名の置換 ' htmlファイルのタグ名を小文字に統一するスクリプトを作りたいと思っています。 ' で、以下のスクリプトを書きました。(問題は置換処理だけなので要点をシンプルに抜き出しました) ' 要素名をすべて記述するのではなく、「<[A-Z]+」等のように記述してヒットした結果を ' 小文字化するなどして置換をおこないたいと思っています。 ' (将来的には属性名も対応したいと思っています) ' ずばりそのものの記述・代替案等を希望しています。 ' よろしくお願いします。 ' ※可能ならコードonlyで会話しましょう。 Option Explicit Dim reg Set reg = New RegExp Function replace(bodyStr, beforeStr, afterStr) reg.Pattern = beforeStr reg.Global = True replace = reg.Replace(bodyStr, afterStr) End Function Dim fileText fileText = "<HTML>HTML</HTML>" ' 要素名の小文字化 ' fileText = replace(fileText, "<HTML+", "<html") ' fileText = replace(fileText, "</HTML", "</html") fileText = replace(fileText, "<[A-Z]+", LCase(RegExp.$1)) If fileText = "<html>HTML</html>" Then MsgBox "期待通り!" Else MsgBox "これじゃダメだよ…orz:" + fileText End If

  • スクリプトの書き方その3

    いつもお世話になります。 XOOPSのコードを読んでいるんですが、沢山の方が関与しているので、 スクリプトの書き方もまちまちです。 そのせいで、素人の私は完全に混乱状態になっています。 ※ PHPマニュアルのサイトでは、preg_xxxっていうのは、 /$str/ とういうように、/(スラッシュ)を使っているので、 !, %, | ? が出てくると、何が正しい書き方なのか全くわかりません。 質問 (1) preg_replace("[\r\n]", "", $str) と preg_replace("/[\r\n]/", "", $str) は同じですか? 質問 (2) preg_replace('!<[^>]*?>!', ' ', $string) と、 preg_replace('/<[^>]*?>/', ' ', $string) は同じですか? 質問 (3) (preg_match('!\W(\w+)$!s', $search, $match) と (preg_match('/\W(\w+)$/s', $search, $match) は同じですか? 質問 (4) preg_replace('?/\*.+\*/?sU', '', $val) の ?とはどういう意味ですか? preg_replace('/\*.+\*/sU', '', $val) と同じですか? それとも、 preg_replace('/?/\*.+\*/?/sU', '', $val) と同じですか? 質問 (5) preg_replace("%(?<!\\\\)'%", "\\'", $string) の、%とはどういう意味ですか? preg_replace("/(?<!\\\\)'/", "\\'", $string) と同じですか? それとも、 preg_replace("/%(?<!\\\\)'%/", "\\'", $string) と同じですか? 迷惑かけますが、どうか、教えて下さい。 よろしくお願いします。

    • 締切済み
    • PHP
  • 文字の置き換え

    ファイルを読み込み、特定の文字を置き換え書き出したいです。 $search = "あいうえお";//置き換え前 $replace = "アイウエオ";//置き換え後 $fp = fopen("index.php", w); $file = file($fp); foreach($file as $key => $val){ $prg = str_replace($search,$replace,$file); fwrite($fp,$prg); } fclose($fp); 上記だとファイルサイズが0になってしまいます。 どのようにすればよいのでしょうか。

    • ベストアンサー
    • PHP
  • rubyの見えない文字

    こんばんは Ruby1.9.2のrails3.1.1を使用しています。 csvファイルをアップロードして、 data = param[:file].read.encode("UTF-8","UTF-8", :invalid => :replace, :undef => :replace, :replace => '').read.encode("UTF-8", :invalid => :replace, :undef => :replace, :replace => '?') のように読み込みまして、最初の1行の最初の要素が"code"でした。そこで、 data[0][0] == "code" としましたところ、falseが出力されました。両方とも文字コードはUTF-8で"code"なのですが、調査したところ data[0][0]length #=> 5 "code".length #=> 4 という違いが見つかりました。 この読み込みデータの見えない文字はなんなんでしょうか。 また、これを取り除く方法は何かありませんでしょうか。よろしくお願いします。 参考 data = param[:file].read.encode("UTF-8", :invalid => :replace, :undef => :replace, :replace => '').read.encode("UTF-8", :invalid => :replace, :undef => :replace, :replace => '?') としたところ、"???code"、長さ7という結果になりました。

  • ファイル操作について

    別スレ立てているので、ルール違反になっちゃいますかね? もしそうであればゴメンナサイ… sub fanc{ my @array = @_; my $ag = shift @array; my $n1 = 'AAA.csv'; my $n2 = 'BBB.csv'; my $n3 = 'CCC.csv'; my $n4 = 'DDD.csv'; my $n5 = 'EEE.csv'; ・ opendir(DIR, "C:/Program Files/Apache Group/Apache2/cgi-bin/test");my @pairs = readdir(DIR); close(DIR); if($ag == 1){@files = grep(/$n1/,@pairs); } if($ag == 2){@files = grep(/$n2/,@pairs); } if($ag == 3){@files = grep(/$n3/,@pairs); } if($ag == 4){@files = grep(/$n4/,@pairs); } if($ag == 5){@files = grep(/$n5/,@pairs); } if($ag == 6){@files = grep(/$n6/,@pairs); } ・ $dfile1 = $files[0]; open(IN,"$dfile1") or exit; chomp(my $row01 = <IN>); chomp(my $row02 = <IN>); chomp(my $row03 = <IN>); chomp(my $row04 = <IN>); chomp(my $row05 = <IN>); chomp(my $row06 = <IN>); ・ close(IN); my @col01 = split(/,/, $row01); my @col02 = split(/,/, $row02); my @col03 = split(/,/, $row03); ・ ・ こういったコードをもっと短く、書くやり方を知りたいです。 grepでヒットするのが複数の場合もあるため、当初はForeach文とフOpenで配列@filesに入った ファイルを全て展開して、配列、又は変数に格納しようと思ったのですが、どうやって複数の配列をOpen関数で扱えばいいのか解りません。 もしそうでなければ、現在は一つのファイルに対しての処理ですが、残ったファイルに関しても関数を回す方法があれば、ご教授願えませんか??あ、あと、CODE(xxxxxx)ってなんのことでしょう?

    • ベストアンサー
    • Perl
  • perlからアマゾンにアクセスできない><

    いつもお世話になっております。 ハックスに記載されているスクリプトを実行したいのですが、エラーとなります。 自分でも調べていますが、perl経験が浅く、原因が特定できません。 修正箇所がわからないので、修正できる方教えて下さい(;へ;) 環境は、XP2で、Activeperl 5.8.8を使用しております。 コマンドラインからused_report.pl 4915512371(←ASIN名:例:ハリーポッター)を実行すると・・・ --------コマンドラインエラー箇所-------- Global symbol "$lastPrice" requires explicit package name at C:\hoehoe\used_report.pl line 32. Global symbol "$avgPrice" requires explicit package name at C:\hoehoe\used_report.pl line 41. Can't find string terminator "EOF" anywhere before EOF at C:\hoehoe\used_report.pl line 44. --------------------------------------- ちなみにブラウザ上ではページも存在し表示されております。 http://www.amazon.co.jp/exec/obidos/tg/stores/offering/list/-/4915512371/used/ 以下スクリプト //////////////////////////////////////////////////////////////// #!/usr/bin/perl # used_report.pl # A script to scrape Amazon, retrieve used listings, and write to a file # Usage: perl used_report.pl <asin> #コマンドラインからASINを取得 my $asin =shift @ARGV or die "Usage:perl used_report.pl <asin>\n"; use strict; use LWP::Simple; #URLを作成 my $url = 'http://www.amazon.co.jp/exec/obidos/tg/stores/offering/list'.'/-/' . $asin . '/used/'; #URLをリクエスト my $content = get($url); die "Could not retrieve $url" unless $content; #変数を設定 my $i = 0; my $totalprices = 0; my $thisPrice = 0; my $highPrice = 0; my $lowPrice = 0; #リスティングをループ while ($content =~ m!<b class=price>\$(.*?)</b>!mgis) { $i++; $thisPrice = $1; if ($thisPrice >= $lastPrice) { $highPrice = $thisPrice; } if ($i == 1 || $thisPrice <= $lowPrice) { $lowPrice = $thisPrice; } $totalprices += $thisPrice; } $avgPrice = $totalprices / $i; #結果を表示 print <<"EOF"; Average Used Price: \$$avgPrice Highest Price: \$$highPrice Lowest Price: \$$lowPrice ////////////////////////////////////////////////////////////////

    • ベストアンサー
    • Perl
  • VBscriptで「改行」と「"」を置換させる

    VBスクリプトを使ってファイルを置換したいと考えています。 以下のVBSファイルとコマンドを使って、置換することはできました。 が、置換対象が「改行」と「"」の場合、エラーとなって置換できません。 どうすればいいのでしょうか。 よろしくおねがいします。 ********コマンド******** (1)cscript replace.vbs "C:\test.txt" "Jim" "Jane" (2)cscript replace.vbs "C:\test.txt" ""_\n" "a_test" ********VBSファイル(replace.vbs)******** Const ForReading = 1 Const ForWriting = 2 strFileName = Wscript.Arguments(0) strOldText = Wscript.Arguments(1) strNewText = Wscript.Arguments(2) Set objFSO = CreateObject("Scripting.FileSystemObject") Set objFile = objFSO.OpenTextFile(strFileName, ForReading) strText = objFile.ReadAll objFile.Close strNewText = Replace(strText, strOldText, strNewText) Set objFile = objFSO.OpenTextFile(strFileName, ForWriting) objFile.WriteLine strNewText objFile.Close (1)のコマンドを実行すると、 「Jim」は「Jane」に置換されますが、 (2)のコマンドを実行すると、エラーになり置換されません。 エラーメッセージ: 「Microsoft VBScript 実行時エラー: インデックスが有効範囲にありません。」 よろしくおねがいします。

  • Perl ランク付け

    名前,順位,点数...etc とテキストファイルにあるなかで、 山本,2,74 鈴木,1,98 山田,3,54 鈴木,1,99 山田,1,100 この場合、1位の数が誰が多いのかを調べたいのですが、 まず for my $D_1(@DATA){ my @temp = split/,/, $D_1; if($temp[1] =~ /1$/){ push(@D_1,$D_1); } } print @D_1; これで、 結果↓ 鈴木,1,98 鈴木,1,99 山田,1,100 このように抽出させたのですが、 ここから、1位が多い人 すなわち、鈴木という値がほしいのですが、どうすればいいのでしょうか?

  • 配列をmb_ereg_replaceで一気に置き換えるには?

    お世話になります。 mb_ereg_replace関数を使い文字の置き換えを行っているのですが、置き換 えるものが多く、1回で置き換えられないかと思い、質問をさせて頂き ます。 // 検索文配列 $search = array("__tome__", "__hame__", "__hoge__"); // 置き換え文配列 $replace = array("$tome", "$hame", "$__hoge__"); // 置き換え $str = mb_ereg_replace($search, $replace, $str1); とやると Warning: mb_ereg_replace() expects parameter 2 to be string, array given in on line というエラーが出てしまい、うまく置き換える事が出来ません。どのようにすればうまく置き換えられるでしょうか? ご教授のほどよろしくお願いします。

    • ベストアンサー
    • PHP
  • 自作したサーバーでperlが動かない

    この度、centos5.3で自宅サーバーを組んだのですが、どうしてもある記述をしたperlのプログラムが動作しません。 他の記述方法であれば、問題なく動作します。 内容としては、htmlをOPENで読み込んで、出力させるだけの単純な物です。 なにか設定が悪いのでしょうか? なお他のサーバーでは、同じプログラムは動作します。 perlのバージョンは、5.8.8です。 記述の内容は次の通りです。 ********************************* #!/usr/local/bin/perl open(HTML, "test.html"); @log = <HTML>; close(HTML); print "Content-type: text/html\n\n"; print <<"EOF"; @log EOF exit; ********************************* エラーログには、Premature end of script headers: test.cgiとなっています。 もちろん、test.htmlファイルも存在します。 どなたかお教え頂けませんでしょうか? 宜しくお願いします。