2015-07-02 3 views
-2

Я пытаюсь заменить строки в огромном файле, содержит много строк.Как изменить «x» и «y» в строке на «y» и «x» с помощью hash

File.txt

line1: "X" = 5.5; "Y" = 7.5; "Z" = 9.0; 
line2: "V" = 66; "Y" = 3; "U" = 11.0; 

так далее ...

заменой хэш (% rhash) содержит информацию о карте

$rhash{"X"} = "Y"; 
$rhash{"Y"} = "X"; 
$rhash{"Z"} = "A"; 
$rhash{"V"} = "B"; 
$rhash{"U"} = "C"; 

, когда я пытался

while (($cur, $cng) = each(%rhash)) { 
    $line =~ s/\Q"$cur"\E/\"$cng\"/g; 
} 

строка 1 - изменение int о либо

"X" = 5.5; "X" = 7.5; "A" = 9.0; 

или

"Y" = 5.5; "Y" = 7.5; "A" = 9.0; 

но правильное изменение

"Y" = 5.5; "X" = 7.5; "A" = 9.0; 

, как я могу добиться этого ..

Спасибо за вашу помощь ...

+0

Примечание: Ключи хэш не только литералы. Ключам может быть любой шаблон, который соответствует (\ S +) – AKS

ответ

1

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

$re = join("|", map { "\\Q$_\\E" } keys(%rhash)); 
$str =~ s/$re/$rhash{$&}/ge; 

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

EDIT Если вам нужно что-то вроде $rhash{"\d+"} = "NUMBER", это должно работать:

sub find_replacement { 
    my ($match, $patterns, $rhash) = @_; 
    foreach my $pattern (@$patterns) { 
    if ($match =~ s/$pattern/$$rhash{$pattern}/e) { 
     return $match; 
    } 
    } 
    die "impossible!"; 
} 

my @patterns = keys(%rhash); 
my $re = join("|", @patterns); 

$str =~ s/$re/find_replacement($&, \@patterns, \%rhash)/ge; 
+0

Спасибо .. Ключи не являются литералами и имеют семантику регулярного выражения – AKS

+0

Спасибо ... Ваше предложение разрешило проблему .. – AKS

Смежные вопросы