2017-02-04 2 views
1

Hier ist ein Beispiel, was ich versuche zu tun: Ich möchte einen Namen für die Eingabe "definiert" und dann, wenn es in eine Funktion genommen wird, nur dann wird es ersetzen alle 3 Variablen.Perl: String der Variable innerhalb einer Variablen

$place_holder = 'f${file_case}_lalal_${subcase}_${test}'; 

.... woanders in einer anderen Funktion:

Lesedatei auf jede Zeile, die 3 Satz von Zahlen, die die $ file_case, $ Unterfall, $ test

Leider
while(<IN>){ 
    ($file_case, $subcase, $tset) = split; 
    $input = $place_holder #### line #3 here needs to fix 
    print " $input \n"; 
} 

repräsentieren Es wird f $ {file_case} lalal $ {subcase} _ $ {test} für jede einzelne Zeile ausgegeben. Ich möchte, dass diese Variablen ersetzt werden. Wie mache ich das, wie ändere ich Zeile 3 um zu ändern, damit ich ausgeben kann, wie ich wollte? Ich möchte den Eingangsnamen im Unterprogramm nicht definieren, er muss im Wesentlichen sein.

+1

Hinweis: Die Interpolation erfolgt nur in Strings mit doppelten Anführungszeichen, aber Ihr Beispiel ist einfach zitiert. –

+0

Ich weiß. Der $ place_holder verhält sich zu diesem Zeitpunkt wie eine Funktion, die 3 Variablen sind noch NICHT bekannt. daher NICHT zu ersetzen. Aber der $ place_holder muss sich an einem Ort befinden, an dem der Benutzer leicht zu dem wechseln kann, was er möchte. Der Rest der Substitution ist in Funktionen verborgen, in denen der Benutzer keine Änderungen vornehmen muss. –

Antwort

3

Sie können es Subroutinen zum Beispiel tun verwenden, wenn das Ihre Kriterien erfüllt

use warnings; 
use strict; 

my $place_holder = sub { 
    my ($file_case, $subcase, $test) = @_;  
    return "f${file_case}_lalal_${subcase}_${test}"; 
} 

# ... 

while (<IN>) { 
    my ($file_case, $subcase, $tset) = split; 
    # 
    # Code to validate input 
    # 
    my $input = $place_holder->($file_case, $subcase, $tset); 
    print "$input\n"; 
} 

I code reference mit einem anonymous subroutine in Erwartung von Anwendungen verwendet haben, die davon profitieren können, aber für die angegebene Aufgabe, die Sie allein kann auch eine normale Subroutine verwenden.

Beachten Sie, dass Sie haben $test und $tset, die nicht die oben genannten betrifft, aber möglicherweise Tippfehler.

+0

Danke. Das ist sicherlich ein Weg, um es elegant zu machen. –

+0

@OngBengSeong Danke - die Punkte, die ich im Sinn hatte, sind, dass es Phasen der Verarbeitung für eine einfachere Verwaltung trennt (zum Beispiel sind genaue Variablennamen egal), die Coderef kann nach Bedarf weitergegeben werden - und es vermeidet ' Eval'-ing Benutzereingabe. – zdim

+0

Was ist, wenn ich 12 verschiedene Dateinamen habe und ich gehe mit Subroutinen-Stil meine $ file_name = sub { } –

-1

evalwhile(<IN>){ ($file_case, $subcase, $tset) = split; $input = eval $place_holder #### line #3 here needs to fix print " $input \n"; }

+0

Leider habe ich das vorher versucht und es funktioniert nicht. Vielen Dank. –

+0

Welchen Fehler haben Sie? Wenn Sie es nicht ausgewählt haben, ist es dasselbe wie Ihre Lösung. Also sollte es funktionieren. – tuxuday

0

A Versuchen Sie, während, nachdem ich geschrieben, ich einen Weg, es zu tun gefunden.

in der Leitung 3 ##, dies zu tun:

($ input = $ place_holder) = ~ s/(\ $ {w} +)/1 $/EEG-;

und alles funktioniert. Ja, der obige Tset ist ein Tippfehler, der als Test gedacht ist. Danke für die Antwort von allen.

+1

Das war es, worüber ich anfangs gewarnt habe - es wertet Benutzereingaben aus. Das ist von Natur aus gefährlich. Ich meine nicht nur mögliche schlechte Absichten, sondern bloße Tippfehler oder falsche Daten können ausgewertet werden, um Ihren Code zu zerstören. Beachten Sie, dass dieser 'Evaluierungs-Inhalt von' $ 1 'als _arbitrary Perl-Code_ gilt. (Deshalb habe ich es in meiner Antwort nicht erwähnt, obwohl ich in einem frühen Kommentar darauf Bezug genommen habe.) Ich schlage vor, dies nicht zu tun, wenn es einen anderen Weg gibt. – zdim

+0

Mit "_user input_" in meinem vorherigen Kommentar meinte ich auch Eingabe von Daten. Wir können nie sicher sein, was in einer "Daten" -Datei ist. Ich würde hinzufügen, dass die Daten vor "/ ee" umfassend verifiziert werden müssten, was "eval" beinhaltet. – zdim

+0

Es ist gut, dass Sie selbst eine funktionierende Lösung gefunden und gepostet haben (übrigens, ich habe sie nicht heruntergesetzt). – zdim

2

können Sie verwenden das String::Interpolate Modul, wie dieser

use String::Interpolate 'interpolate'; 

my $place_holder = 'f${file_case}_lalal_${subcase}_${test}'; 


while (<IN>) { 
    my ($file_case, $subcase, $test) = split; 

    my $input = interpolate($place_holder); 
    print "$input\n"; 
} 

Das Modul Zugriff auf Perl gibt Code eingebauten in C, die doppelte Anführungszeichen Interpolation durchführt, so dass es im Allgemeinen schnell und präzise

Verwandte Themen