Как использовать Perl для выполнения подстановок на основе расчетов? - PullRequest
3 голосов
/ 10 марта 2011

Я пытаюсь написать 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 вместо вычисления выражения.

Я новичок в Perl, поэтому любая помощь будет принята с благодарностью. Заранее спасибо,

1010 * Дан *

Редактировать: Решение (на основе ответа Романа)

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

Кроме того, решение Шона также отлично сработало для меня. Спасибо всем!

Ответы [ 2 ]

4 голосов
/ 10 марта 2011

Вот отдельная подпрограмма, которая сделает эту работу.Он использует специальную переменную $^I, которая активирует функцию редактирования на месте Perl.(См. Справочную страницу perlvar для получения дополнительной информации о $^I и справочную страницу perlrun для получения информации о переключателе командной строки -i, который включает редактирование на месте.)

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' на '' выше, если вы не хотите создавать резервную копию.

Возможно, вы захотите настроить регулярное выражение для распознавания чисел.Как написано, он не будет соответствовать числам без конечной десятичной точки и хотя бы одной цифры.Я думаю, вы также хотите, чтобы -? соответствовал необязательному знаку минус, а не -*, который будет соответствовать любому количеству знаков минус.Выполнение арифметики над строкой с более чем одним начальным знаком минус почти наверняка не даст того, что вы хотите.

4 голосов
/ 10 марта 2011
s/(-*\d+.\d+)/$scalingFactor*$1/ge

(уведомление e в конце)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...