如何使用Perl根据计算执行替换?

时间:2011-03-10 06:34:12

标签: regex perl file-io

我正在尝试编写一个perl脚本来搜索文本文件,查找所有十进制数字,并通过一些缩放因子修改它们。到目前为止,我已成功用正则表达式提取数字:

open(INPUT, $inputPath) or die "$inputPath cannot be opened.";

while ($thisLine = <INPUT>) {
  while ($thisLine =~ m/(-*\d+\.\d+)/g) {
    if(defined($1)) { 
      $new = $scalingFactor*$1;
      print $new."\n";
    }
  }
}

close (INPUT);

但是,我还没想出如何将新值重新插入文件中。我尝试使用s/(-*\d+.\d+)/$scalingFactor*$1/g进行替换,但当然这会插入$scalingFactor的字符串表示而不是评估表达式。

我是个新手,所以任何帮助都会非常感激。提前谢谢,

-Dan

编辑解决方案(基于罗马的回复)

while ($thisLine = <INPUT>) {
  $thisLine =~ s/(-*\d+\.\d+)/$scalingFactor*$1/ge;
  prinf OUTPUT $thisLine;
}

或者,肖恩的解决方案对我来说也很有用。谢谢大家!

2 个答案:

答案 0 :(得分:4)

s/(-*\d+.\d+)/$scalingFactor*$1/ge

(最后注意e

答案 1 :(得分:4)

这是一个独立的子程序,可以完成这项工作。它使用特殊变量$^I,它激活Perl的就地编辑功能。 (有关$^I的更多信息,请参阅“perlvar”手册页;有关-i命令行开关的信息,请参阅“perlrun”手册页,该命令行开关将启用就地编辑。)

use strict;  # Always.

sub scale_numbers_in_file_by_factor {
    my ($path, $scaling_factor) = @_;
    local @ARGV = ($path);
    local $^I = '.bak';
    while (<>) {
        s/ ( -? \d+ \. \d+ ) / $scaling_factor * $1 /gex;
        print;
    }
}

scale_numbers_in_file_by_factor('my-file.txt', .1);

通过将'.bak'附加到原始文件名来创建备份文件。如果您不想备份,请将'.bak'更改为''

您可能想要调整识别数字的正则表达式。如上所述,它不会匹配没有尾随小数点和至少一个数字的数字。我想你也希望-?匹配一个可选的减号,而不是-*,它将匹配任意数量的减号。对具有多个前导减号的字符串执行算术几乎肯定不会达到您想要的效果。