文字の置換がうまくいかない

このQ&Aのポイント
  • テキストファイルを読み込み、文字の置換を行いたいがうまくいかない。
  • テキストファイルの中で特定の文字列を置換する際に、正規表現の書き方に誤りがある可能性がある。
  • 一部の置換処理は成功したが、特定の文字列の置換がうまくいかない。
回答を見る
  • ベストアンサー

文字の置換がうまくいかない

********** test.txt ************* $first = "abc"; $last = "xyz"; ********************************* ********** change.txt *********** $first $firstaaa $last ********************************* という2つのテキストファイルがあったとして、 open(IN,"test.txt"); @data = IN; close IN; open(A,"change.txt"); while(<A>){$a_data .= $_} close A; foreach (@data) { if(/(\$[a-zA-Z_]+)[\t\s]*=[\t\s]*"(.+)"[\t\s]*;/){ my $name = $1; my $value = $2; print "$name<br>"; #$nameに何が入っているか表示 $a_data =~ s/$name/$value/g; } } としても、change.txtの$firstや$lastがabcや、xyzに置換されないのですが、なにがいけないのでしょうか?print "$name<br>";のところではちゃんと$firstと$lastという風に出力されています。$a_data =~ s/$name/$value/g;を$a_data =~ s/\$first/$value/g; と変えると、ちゃんと$firstだけ置換されました。 なにか心当たりがある方、よろしくお願いします。

  • arcsin
  • お礼率46% (194/417)
  • Perl
  • 回答数1
  • ありがとう数1

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

  • ベストアンサー
  • leaz024
  • ベストアンサー率75% (398/526)
回答No.1

$name の値が '$first' のとき、正規表現では(firstの頭についている)$ が行末を示すメタ文字と認識されるため、置換されないのです。 正規表現に使用する文字列にメタ文字が含まれる場合は、メタタグの \Q~\E を使うか、予め quotemeta でエスケープします。 ・\Q~\E の場合  my $name = $1;  my $value = $2;  $a_data =~ s/\Q$name\E/$value/g;  # \Q~\Eで挟まれた部分のメタ文字は無効化されます。  # この場合 $name が変数展開された後、$first の $ が無効化されます。 ・quotemeta の場合  my $name = quotemeta($1); # $name は '\$first' となります。  my $value = $2;  $a_data =~ s/$name/$value/g; # 比較のため同じ部分を書きましたが、それぞれ変更箇所は1行ずつです。

arcsin
質問者

お礼

ありがとうございます。 無事、出来ました

関連するQ&A

  • 入力したテキストを置換するプログラミングを作りたいのですが上手くいかず

    入力したテキストを置換するプログラミングを作りたいのですが上手くいかず困っています。 テキストエリアに文章を入力し、 次に置換前の文字と置換後の文字をそれぞれ入力する形にして置換をしようと考えています。 最終的に置換前の文字と置換後の文字を入力する欄を複数用意して 複数の置換を一度で行ないたいと思っています。 ですが下記の「a1」に入力した置換前の文字全て削除され「a2」の内容に変換されません。 初心者なので根本的に間違ってるかもしれませんが、わかる方よければ教えてください。 ----------------- <form method="post" action="form.cgi"> <textarea name="chikan" rows="10" cols="70"></textarea><br> <input type="text" name="a1" size="50">を<input type="text" name="a2" size="50">に変換<br><br> </p> <p><input type="submit" value="置換"></p> </form> ----------------- ----------------- #!/usr/local/bin/perl if ($ENV{'REQUEST_METHOD'} eq 'POST') { read(STDIN, $alldata, $ENV{'CONTENT_LENGTH'}); } else { $alldata = $ENV{'QUERY_STRING'}; } foreach $data (split(/&/, $alldata)) { ($key, $value) = split(/=/, $data); $value =~ s/\+/ /g; $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack('C', hex($1))/eg; $value =~ s/\t//g; $value =~ s/\n//; $in{"$key"} = $value; $in{'chikan'} =~ s/\Q$in{'a1'}\E/$in{'a2'}/g; } print"Content-type: text/html\n\n"; print <<"EOM"; <html> <head><title></title> </head> <body> <textarea name=area rows=50 cols=70> $in{'chikan'} </textarea> </form> </body> </html> EOM exit; -------------------------

    • ベストアンサー
    • CGI
  • 文字列の置換

    JAVAであるファイル内の文字列を置換するプログラム(日本語)を作りたいのですが、 ・ ・ String h_s; FileReader h_fr = new FileReader(in_filename); BufferedReader h_br = new BufferedReader(h_fr); while(true){  h_s = h_br.readLine();  if (h_s == null){   break;  }  ●文字列を置換するプログラム● } ・ ・ ここの●文字列を置換するプログラム●にあたる適当な関数って何かありますか? たとえばperlでいうと↓みたいなものなのですが・・・ s/置換前文字/置換後文字/g よろしくお願いします。

    • ベストアンサー
    • Java
  • ”ァー”が含まれている文字を置換すると文字化け

    OS:solaris8 perlのver:5.8.6 perlで、”ァー”が含まれている文字列に対し、 全角スペースを半角スペースに置換しようとすると 文字化けしてしまいます。 (”ぁー”でもどうようでした) ”ぃー”や”ぅー”、”ぁ”では 問題無いのですが…。 当方、perl初心者&文字コードに詳しくないため、 原因がよくわからないでいます。 どなたか原因をおわかりの方、 ご教授お願いいたします。 文字コードはEUCです。 以下はソースです my $line = "ファイヴァー スコープ 眼鏡"; $line =~ s/\t/ /g; # タブを半角スペースに置換する print '$line2='.$line."<br>\n"; $line =~ s/ / /g; # 全角スペースを半角スペースに置換する print '$line3='.$line."<br>\n"; #↑ここで文字化けしてしまいます $line =~ s/^\s+//; # 頭の空白を除く print '$line4='.$line."<br>\n"; $line =~ s/\s+$//; # 尻の空白を除く print '$line5='.$line."<br>\n";

    • ベストアンサー
    • Perl
  • UNIX のシェル 文字の置換について

    シェルでファイルの文字列を置換したいです。 /*~*/のコメントの文字なので、1行数を変えたくないです。 ─────────────────────────── ※1文字分の空白を「_」で表示します。 test.txtファイルの「XXXXX」を「aa___」に置換する。 ─────────────────────────── 【test.txt 置換前】 /**************/ /*_XXXXXYYYYY_*/ /**************/ 【シェルの内容 test.sh】 #!/bin/csh set IN_henkan = `printf "%-5s" $1` perl -i -p -e 's/XXX/'$IN_henkan'/g' test.txt 【シェルを実行】 test.sh aa 【test.txt置換前 希望する状態】 /**************/ /*_aa___YYYYY_*/ /**************/ 【test.txt置換前 実際の状態】 /**************/ /*_aa_YYYYY_*/ /**************/ ─────────────────────────── 「aa」の後ろに1文字分の空白しか挿入されないです。

  • Perlの文字列置換について

    質問です。文字列の置換を行いたいのですが、まずはソースから・・・ use File::Basename; use File::Copy; use File::Find; use File::Path; my @filelist = (); $inputfile='C:\Users\test.txt'; $outputfile='C:\Users\test_new.txt'; open (IN, $inputfile) or die "$!"; open (OUT, ">$outputfile") or die "$!"; while(<IN>) { $str = $_; if ($str =~ /html:text/) { $str =~ s/html:text/s:textfield/g; $str =~ s/property/name/; $str =~ s/styleClass/cssClass/; elsif($str =~ /html:textarea/) { $str =~ s/html:textarea/s:textarea/g; $str =~ s/property/name/; $str =~ s/style/cssStyle/; $str =~ s/styleClass/cssClass/; } print OUT $str; } close (IN); close(OUT); sub wanted{ push(@filelist, $File::Find::dir."/$_") unless ($_ =~ /^\.$/); } Perlプログラムで下記のソースを一括置換します。 <html:text property="xxx" styleClass="yyy"> <html:textarea property="abc" styleClass="def" style="ghi"> 目標は以下のように置換したいです <s:textfield name="xxx" cssClass="yyy"> <s:textarea name="abc" cssClass="def" cssStyle="ghi"> しかし、上記のプログラムを実行すると <s:textfield name="xxx" cssClass="yyy"> <s:textfieldarea name="abc" cssClass="def" style="ghi"> となってしまいます。 どこをどう直せばよいのかわからないので誰か教えてください。 お願い致します!!

    • ベストアンサー
    • Perl
  • Perlのs///を使った置換で質問です

    s///のパターンマッチ演算子を使った置換で、 <br>→<br /> に置換するときははどうしたらいいのでしょうか? ↓これでは<br />の/が引っかかってできないようです・・・。 $content =~ s/<br>/<br />/g;

    • ベストアンサー
    • Perl
  • DOSのバッチで、テキストファイル中の文字を置換したい

    いつもお世話になっております。 WindwsXPでDOSバッチを使ってテキストファイル中にある文字列1を文字列2に置換したいのです。 ネットをさまよっていて、こんな例を見つけました。 (参考にしたのはここです。http://www.fpcu.jp/dosvcmd/bbs/log/cat3/cat54/2-0391.html) ====================== @echo off if "%1"=="" goto end set fname=%1 copy %fname% org >nul type nul >%fname% for /f "tokens=1* delims=" %%a in ( org ) do (set line=%%a&& call :sub) del org goto end :sub :この1行下の acb=xyz に置換前と置換後の文字列を指定する。 set l=%line:abc=xyz% echo %l%>>%fname% goto :EOF :end ====================== これをsample.batという名前で保存し、DOSのウィンドウでsample < a.txt と打つと、a.txtファイル中の"abc"が"xyz"に置き換わります。 これに手を入れて置換前と置換後の文字列を可変にしたく思い、sub中に set mae=abc set ato=xyz の2行を加え、変数に値を設定するようにしました。 ところが、次の1行の書き変え方がわかりません。 set l=%line:abc=xyz% を set l=%line:%abc%=%xyz%% のように変えてみましたが、うまく動きません。 どなたかご教授いただけませんか。DOSだけでファイル中の文字列の置換ができればset文を使う使わないにはこだわりません。

  • perl cgi 文字コード変換について

    掲示板でログファイルへの書き出しの際に文字コードをshift-jisに変更したいのですが, #投稿された値を受け取る if ($ENV{'REQUEST_METHOD'} eq 'POST') { read(STDIN, $alldata, $ENV{'CONTENT_LENGTH'}); } else { $alldata = $ENV{'QUERY_STRING'}; } foreach $data (split(/&/, $alldata)) { ($key, $value) = split(/=/, $data); $value =~ s/\+/ /g; $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack('C', hex($1))/eg; $value =~ s/\t//g; $in{"$key"} = $value; } #ヘッダの表示 print "<html>\n"; print "<head><title>掲示板</title></head>\n"; print "<body>\n"; #受け取ったデータをファイルに書き込む if ($in{'handle'} ne '' && $in{'message'} ne '') { if (open(FH, "bbs.txt")) { @file = <FH>; close(FH); use CGI; $cgi=new CGI; $name1=$cgi->param('handle'); $name2=$cgi->param('number'); use Encode; use Encode::Guess qw(euc-jp shiftjis 7bit-jis); encode("shiftjis",decode('Guess',$name1)); encode("shiftjis",decode('Guess',$name2)); unshift(@file, "$name1\t$name2\n"); ##この部分で if (open(FH, ">bbs.txt")) { print FH @file; close(FH); } else { print "<p>ファイルに書き込めません。</p>"; } } else { print "<p>ファイルを読み込めません。</p>"; } } #投稿フォームの表示 print "<form method=\"post\" action=\"bbs.cgi\">\n"; print "<p>\n"; print "ハンドルネーム<br>\n"; print "<input type=\"text\" name=\"handle\" size=\"20\" value=\"\"><br>\n"; print "メッセージ<br>\n"; print "<input type=\"text\" name=\"message\" size=\"20\" value=\"\">\n"; print "</p>\n"; print "<p><input type=\"submit\" value=\"送信する\"></p>\n"; print "</form>\n"; #記事の一覧表示 if (open(FH, "bbs.txt")) { while ($data = <FH>) { ($handle, $message) = split(/\t/, $data); print "<p>\n"; print "投稿者:$handle<br>\n"; print "メッセージ:$message\n"; print "</p>\n"; } } else { print "<p>ファイルを読み込めません。</p>"; } #フッタの表示 print "</body>\n"; print "</html>\n"; exit; このような感じでかいたのですが文字コードを変更し,unshift(@file, "$name1\t$name2\n");と記述すると何も書かれずに空白になってしまいます..なぜでしょうか?困っています.教えて下さい. ちなみにunshift(@file, "$in{'handle'}\t$in{'message'}\n"); と文字コードの変更を意識しなかった場合にはちゃんとファイルに書かれています. jcode.plなどは使わずにencodeで行いたいです.

    • ベストアンサー
    • Perl
  • jcodeコンバートさせた後の置換処理が無効になるのはなぜ

    jcodeコンバートさせた後の置換処理が無効になるのはなぜですか? foreach $pair (@pairs) { ($name, $value) = split(/=/, $pair); &jcode'convert(*name,'sjis'); &jcode'convert(*value,'sjis'); #jcode'convertの後ではNG------------# $value =~ s/://g; $value =~ s/,//g; } foreach $pair (@pairs) { ($name, $value) = split(/=/, $pair); #jcode'convertの前ならOK------------# $value =~ s/://g; $value =~ s/,//g; &jcode'convert(*name,'sjis'); &jcode'convert(*value,'sjis'); }

    • ベストアンサー
    • Perl
  • sedの置換文字に変数を使用したいのですが・・・

    あるファイルの特定の文字を変換し、上書きをする処理を行いたいのですが、sedの置換文字に変数が渡せなくて困っています。 例: X="a" Y="b" echo test.txt | sed 's/${X}/${Y/g}' >test.txt sedでは置換文字に${X}といった変数を使用することはできないのでしょうか?