/ / Jak używać Perla do wykonywania podstawień na podstawie obliczeń? - wyrażenie regularne, perl, plik-io

Jak używać Perla do wykonywania podstawień na podstawie obliczeń? - regex, perl, file-io

Próbuję napisać skrypt Perla do przeszukiwaniaw pliku tekstowym znajdź wszystkie liczby dziesiętne i zmodyfikuj je o jakiś współczynnik skalowania. Do tej pory udało mi się wyodrębnić liczby za pomocą wyrażeń regularnych:

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);

Jednak jeszcze nie wymyśliłem, jak ponownie wstawić nowe wartości do pliku. Próbowałem użyć s/(-*d+.d+)/$scalingFactor*$1/g do podstawienia, ale oczywiście to wstawiło reprezentację ciągu $scalingFactor zamiast oceniać wyrażenie.

Jestem początkującym perlem, więc każda pomoc byłaby bardzo mile widziana. Z góry dziękuję,

-Dan

Edytować: Rozwiązanie (na podstawie odpowiedzi Romana)

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

Alternatywnie, rozwiązanie Seana również działało świetnie dla mnie. Dzięki wszystkim!

Odpowiedzi:

4 dla odpowiedzi № 1
s/(-*d+.d+)/$scalingFactor*$1/ge

(ogłoszenie e na końcu)


4 dla odpowiedzi nr 2

Oto samodzielny podprogram, który wykona zadanie. Używa specjalnej zmiennej $^I, który aktywuje funkcję edycji lokalnej Perla. (Zobacz stronę podręcznika "perlvar", aby uzyskać więcej informacji na temat $^Ii stronę podręcznika "perlrun", aby uzyskać informacje o programie -i przełącznik wiersza polecenia, który włącza edycję lokalną).

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);

Plik kopii zapasowej zostanie utworzony poprzez dołączenie ".bak" do oryginalnej nazwy pliku. Zmienić ".bak" do "" powyżej, jeśli nie chcesz kopii zapasowej.

Możesz zmodyfikować wyrażenie regularne rozpoznające liczby. Jak napisano, nie będzie dopasowywać liczb bez końcowego kropki dziesiętnej i co najmniej jednej cyfry. Myślę, że ty też chcesz -? aby dopasować opcjonalny znak minus, nie -*, który będzie pasował do dowolnej liczby znaków minus. Wykonywanie działań arytmetycznych na łańcuchu z więcej niż jednym wiodącym znakiem minus prawie na pewno nie zrobi tego, co chcesz.


-1 dla odpowiedzi nr 3

Otwórz uchwyt pliku zapisu o nazwie OUTPUT i zrób drukuj OUTPUT $ nowy