2016-04-08 20 views
2

Ich möchte eine kompilierte Regexp dynamisch erstellen. Nun, kein Problem:Kurze Möglichkeit zum kompilieren dynamisch erstellten Regexp

Ich möchte es kompilieren, um Overhead bei wiederholten Anrufen zu vermeiden. Auch kein Problem:

$rx = qr/$rx/; 

Was ist das Problem - es ist zu lang für solch eine triviale Operation. Zwei Zeilen und zwei zusätzliche Male muss ich Variablenname erwähnen, also müsste ich es in allen 3 Positionen ändern, wenn ich mich entscheide, es umzubenennen.

Bisher habe ich kommen entweder mit einem Helfer-Funktion (die Nachteile haben würde immer noch von dieser Funktion irgendwo zu haben halten):

sub qr_expr { qr/$_[0]/ } 
# and later 
my $rx = qr_expr(join('|', keys %replacement_hash)); 

oder nur einfach die gleiche Funktion inlining wo ich es brauche:

my $rx = sub{qr/$_[0]/}->(join('|', keys %replacement_hash)); 

Gibt es eine Möglichkeit, es prägnanter zu schreiben?

+3

Sie nutzen könnten [ 'map'] (http://perldoc.perl.org/functions/map.html):' my ($ rx) = map {qr/$ _ /} join ('|', Schlüssel% ersetzung_hash) '. –

+0

@HunterMcMillen, gute Eins! Wenn nur kein zusätzlicher Kontext benötigt wird() arond 'my' Liste ... –

+0

Map gibt eine Liste zurück, wenn Sie nur das erste Element erfassen wollen (in diesem Fall gibt es nur ein Element) müssen Sie Klammern verwenden, Andernfalls erhalten Sie die Größe der Liste. –

Antwort

3
my ($re) = map qr/$_/, join '|', map quotemeta, @strings; 

Wahrscheinlich müssen Sie es nicht kompilieren.

Die meiste Zeit, Sie am Ende es in einem anderen Muster einbetten (z. B. /^$re\z/ oder /($re)/), zwingt das Muster neu kompiliert werden. (/$re/ kompiliert nicht, und auch nicht das Äquivalent =~ $re.)

Darüber hinaus zwischenspeichert Perl die kompilierte Form des letzten von ihm kompilierten Musters. Wenn das gleiche Muster erneut kompiliert werden soll, wird stattdessen die zwischengespeicherte Kopie zurückgegeben.

In diesen beiden Situationen wäre folgendes genügen:

my $pat = join '|', map quotemeta, @strings; 
+0

Während normale Saite in der Tat ziemlich gleichauf mit 'qr //' ist, scheint '/ o' zu meiner Überraschung noch 5-10% zu erhöhen. Ich hoffte, wir haben es vor langer Zeit losgeworden. –

Verwandte Themen