Заменить текст в файле значением из хэша - PullRequest
1 голос
/ 28 февраля 2020

У меня есть perl ha sh, который выглядит следующим образом:

{
  "case1"   => 0.05,
  "case2"   => 0.105,
  "case3"   => -0.006,
  "case4"   => -0.0005,
  "case5"   => 0.0501,
  "case6"   => 0.098,
  "case7"   => 0.16,
}

Как я могу использовать ключ ha sh для замены соответствующего ключа в тексте значением. Пример текстового файла:

 set case1
 set case5
 set case3
 set case4

Ответы [ 3 ]

3 голосов
/ 28 февраля 2020

Создайте регулярное выражение из ключей

my $regex = join '|', map quotemeta, keys %hash;

Затем используйте его для замены

s/($regex)/$hash{$1}/g;

Когда ключи имеют разную длину, вам может потребоваться сначала отсортировать их по длине перед созданием регулярное выражение.

Итак, полный пример:

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

my %hash = (
    case1 => 0.05,
    case2 => 0.105,
    case3 => -0.006,
    case4 => -0.0005,
    case5 => 0.0501,
);

my $regex = join '|', map quotemeta, keys %hash;
while (<DATA>) {
    s/($regex)/$hash{$1}/g;
    print;
}

__DATA__
 set case1
 set case5
 set case3
 set case4
0 голосов
/ 28 февраля 2020

Или, если порядок строк значительный, следующий код сохраняет его

use warnings;
use strict;
use feature 'say';

my %hash = (
    case1 => 0.05,
    case2 => 0.105,
    case3 => -0.006,
    case4 => -0.0005,
    case5 => 0.0501,
);

my $data = do { local $/; <DATA> };

for my $k(keys %hash) {
    $data =~ s/$k/$hash{$k}/g;
}

say $data;

__DATA__
set case1
set case5
set case3
set case4

Вывод

set 0.05
set 0.0501
set -0.006
set -0.0005
0 голосов
/ 28 февраля 2020

Желаемый результат получен с немного другим кодом

use warnings;
use strict;
use feature 'say';

my %hash = (
    case1 => 0.05,
    case2 => 0.105,
    case3 => -0.006,
    case4 => -0.0005,
    case5 => 0.0501,
);

my @data = <DATA>;

chomp @data;

@data = map { s/(case\d)/$hash{$1}/ && $_ } @data;

say for @data;

__DATA__
set case1
set case5
set case3
set case4

Вывод

set 0.05
set 0.0501
set -0.006
set -0.0005
...