2

次の行を含む「input.file」という名前のファイルがあります。

フーは$COLORです

$COLOR には「赤」が割り当てられており、次の行で「output.file」という名前の 2 番目のファイルを作成しようとしています。

フーは赤い

これが私の失敗した試みです:

#!/usr/bin/perl
use strict;
use warnings;

my $COLOR = "red";

open(FILE_IN, "< input.file");
open(FILE_OUT, "> output.file");

while (<FILE_IN>){

    # Prints 'Foo is $COLOR' to 'output.file'
    print FILE_OUT;
}

close FILE_IN;
close FILE_OUT;

# Prints 'Foo is red' to STDOUT
print "Foo is $COLOR\n";

'output.file' に出力するとき、'$COLOR' ではなく 'red' を出力するにはどうすればよいでしょうか?

ありがとう

4

1 に答える 1

4

一般的な解決策

文字列に正規表現に一致するプレースホルダーが含まれていると仮定しましょう/\$\w+/。また、名前を値にマッピングするハッシュもあります。

my %replacements = (
  COLOUR => 'red',
  x => 42,
  perl_snippet => '$x++ == 3',
);

したがって、入力

my $input = <<'END';
My favourite colour is $COLOUR.
The meaning of life is $x. Here is some Perl: `$perl_snippet`
$undefined
END

に変換する必要があります

My favourite colour is red.
The meaning of life is 42. Here is some Perl: `$x++ == 3`
$undefined

そしてそうではない

My favourite colour is red.
The meaning of life is 42. Here is some Perl: `42++ == 3`

これは、名前をハッシュ キーとして使用してプレースホルダーを照合し、置換ハッシュに適切なエントリが存在する場合にのみ置換することで実現できます。

(my $output = $input) =~
   s/\$(\w+)/exists $replacements{$1} ? $replacements{$1} : '$'.$1/eg;

また

(my $output = $input) =~
   s/\$(\w+)(?(?{exists $replacements{$1}})|(*F))/$replacements{$1}/g;

ハッシュで単一の置換を使用するこの戦略は、文字列の各部分が一度だけ評価され、二重補間が発生しないことも保証します。

具体的な解決策

1 つのプレースホルダーのみを補間する必要がある場合は、ハッシュを使用しないことで簡略化できます。

s/\$COLOR/red/g;

これには次の欠点があります。

  • そのような交換品は 1 つしか持てません。別のものを追加するs///と、通常はバグである二重エスケープが可能になります。
  • 実行時に置換値またはプレースホルダーを簡単に照会または変更することはできません。
于 2013-06-04T22:54:42.010 に答える