Wie kann ich mit Perl eine dynamische Regexp erstellen, indem ich ein Argument an eine Subroutine übergebe?

7

Ich möchte Subroutine mit einem dynamisch erstellten Regxp erstellen. Hier ist, was ich bisher habe:

%Vor%

Es sieht so aus, als würde es funktionieren, aber es scheint so, als wenn das $ int in der Regex zum ersten Mal ausgewertet wird, es für immer da ist.

Gibt es irgendwie etwas Ähnliches, aber muss die Regex das neue Argument jedes Mal aufsammeln, wenn das Sub aufgerufen wird?

    
messick 01.05.2009, 05:46
quelle

4 Antworten

16

Der einfachste Weg, Ihren Code zu korrigieren, besteht darin, runde Klammern um my einzufügen und ??{ zu entfernen. Hier ist das feste Programm:

%Vor%

Eine der problematischen Zeilen in Ihrem Code war my $int = @_ , was äquivalent zu my $int = 1 war, da% ce_de% im skalaren Kontext ausgewertet wurde, was die Anzahl der Elemente in @_ ergibt. Verwenden Sie @_ , um my($int) = @_; im Listenkontext auszuwerten, oder rufen Sie das erste Element mit @_ ab, oder holen Sie + das erste Element mit my $int = $_[0];

, um das erste Argument Ihrer Untergruppe zu erhalten

Es gab ein ähnliches Problem in der my $int = shift; -Zeile, Sie benötigen auch die Klammern, um die regexp-Übereinstimmung im Listenkontext auszuwerten, die Liste von my $var2 = zu erhalten und (, , ...) zuzuordnen.

Das Konstrukt $var2 = , das Sie verwenden wollten, hatte den gegenteiligen Effekt zu dem, was Sie wollten: (unter anderen Dingen) kompilierte es Ihre Regexp das erste Mal, als es für das Matching verwendet wurde. Für Regexps, die (??{...}) oder $ enthalten, aber @ nicht enthalten, kompiliert Perl die Regexp automatisch für jede Übereinstimmung, es sei denn, geben Sie das ??{...} -Flag an (z. B. o ).

Das Konstrukt m/$int/o bedeutet: Benutze den Perl-Code (??{...}) , um eine Regexp zu erzeugen, und füge diese Regexp hier ein. Um weitere Informationen zu erhalten, suchen Sie nach ... auf Ссылка . Der Grund, warum es in Ihrem Beispiel nicht funktionierte, wäre, dass Sie eine zusätzliche Klammer benötigt hätten, um ??{ einzufangen, aber selbst mit hätte es nicht funktioniert, weil my ($var2) = $var =~ m/((??{$int}))/ eine undokumentierte Eigenschaft hat: Es erzwingt die Kompilierung des Arguments, wenn das Regexp zum ersten Mal zum Vergleichen verwendet wird. Daher hätte ??{ immer my ($var2) = $var =~ m/((??{$int + 5}))/ gefunden.

    
pts 01.05.2009, 05:52
quelle
3
%Vor%

Dies gibt Ihnen die Anzahl der Parameter, in Ihrem Fall immer '1'.

Ich denke du willst

%Vor%     
Thilo 01.05.2009 06:00
quelle
3

Um einen regulären Ausdruck dynamisch an eine Funktion zu übergeben, anstatt ihn dynamisch in der Funktion zu erstellen, verwenden Sie qr //.

%Vor%

qr // akzeptiert dieselben nachgestellten Argumente wie m //: i, m, s und x

    
Craig Lewis 02.05.2009 01:33
quelle
0

mein $ int ist der skalare Kontext, er hat ($ int) für den Listenkontext und setzt $ _ [0] in $ int. Im Folgenden werden nur 10 in $ int und die restlichen 11 bis 99 sind verloren.

mein ($ int) = (10..99); drucke $ int; 10

    
hpavc 01.05.2009 07:07
quelle

Tags und Links