- ベストアンサー
正規表現での置き換え
正規表現置き換えについて -----入力 ----- a (b) B (C) test.csv file.dat -----出力 ----- b (a) C (B) file.csv test.dat --------------- としたくて以下のコードを書いたのですが 実際の出力が $2 ($1) $2 ($1) $2.csv $1.dat となってしまいます。 --以下ソース %Convert = ( '(.+) \\((.+)\\)', '$2 ($1)' ,'(.+)\\.csv (.+)\\.dat', '$2.csv $1.dat' ); while(<DATA>){ foreach $key ( keys %Convert ){ s/$key/$Convert{$key}/gi; } print; } __DATA__ a (b) B (C) test.csv file.dat
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
正規表現の置換部を2回ダブルクォート文字列として評価するとうまくいきます。 %Convert = ( '(.+) \\((.+)\\)', '$2 ($1)' ,'(.+)\\.csv (.+)\\.dat', '$2.csv $1.dat' ); while(<DATA>){ foreach $key ( keys %Convert ){ s/$key/"\"$Convert{$key}\""/giee; } print; } __DATA__ a (b) B (C) test.csv file.dat 1回目の評価で置換部は "$2 ($1)" となり、2回目の評価で $2 と $1 がそれぞれ置き換えられます。
その他の回答 (4)
- sakusaker7
- ベストアンサー率62% (800/1280)
なんとなく別解。 require 5.008; use strict; my %Convert = ( # '(.+) \\((.+)\\)', '$2 ($1)' # ,'(.+)\\.csv (.+)\\.dat', '$2.csv $1.dat' '(.+) \\((.+)\\)', '%2$s (%1$s)' ,'(.+)\\.csv (.+)\\.dat', '%2$s.csv %1$s.dat' ); while(<DATA>){ foreach my $key ( keys %Convert ){ #s/$key/$Convert{$key}/gi; s/$key/sprintf $Convert{$key}, $1, $2/gie; } print; } __DATA__ a (b) B (C) test.csv file.dat データをちょっといじってますが、 b (a) C (B) file.csv test.dat となります。
- Tacosan
- ベストアンサー率23% (3656/15482)
ん~, 手元で実験した限りでは, 2つ目は '(.+)\\.csv (.+)\\.dat', '"$2.csv $1.dat"' でいいような気がしますが....>#2. まあ, 確かにちょっと面倒かも.
- sakusaker7
- ベストアンサー率62% (800/1280)
すみません。確認したら#1ではだめですね。 my %Convert = ( '(.+) \\((.+)\\)', '"$2 ($1)"' ,'(.+)\\.csv (.+)\\.dat', '"$2" . "csv" . " $1" . ".dat"' ); while(<DATA>){ foreach my $key (keys %Convert){ s/$key/$Convert{$key}/giee; } print; } __DATA__ a (b) B (C) test.csv file.dat 元データの定義が面倒なのと、evalが2回必要です。 #たぶん使いまわせるモジュールがあると思いますが
- sakusaker7
- ベストアンサー率62% (800/1280)
evaってください。 s/$key/$Convert{$key}/gi; } → s/$key/$Convert{$key}/gie; } たぶんこれで。