Thread Maske Regex
(14 answers)
Opened by hobbyperler at 2009-09-12 09:47
Okay, dann hier nochmal der Code, etwas verändert und kommentiert, mit einem kleinen Beispiel:
Code (perl): (dl
)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 #!/usr/bin/perl use strict; use warnings; # In %special werden die Bedeutungen der, von Sternchen umgebenen Ausdrücke # abgelegt: my %special = ( 'id' => "\\d+", # *id* => \d+ '' => "\\*", # ** => \* ); sub mask2regex { my( $mask ) = @_; # Hier nutze ich ein feature von split(). Falls geklammerte Ausdrücke in # dem Regex vorhanden sind, werden die matchenden Teile an ihrer jeweiligen # Position mit zurückgeliefert. Die Wörter, die von Sternchen umgeben sind, # stehen also an ungeraden, die konstanten Teile an geraden Indizes in @rx: my @rx = split /\*(\w*)\*/, $mask; # Jetzt werden die einzelnen Teile wieder zusammengefuegt. Dabei werden # Zeichen mit besonderer Bedeutung in den konstanten Teilen escaped # (\Q...\E) und die Stern-Ausdrücke werden durch ihre Pendants aus %special # ersetzt: my $rx; $rx .= $_ % 2 == 0 ? "\Q$rx[$_]\E" : $special{$rx[$_]} for 0 .. $#rx; # Mir ist noch aufgefallen, dass der Ausdruck vermutlich nicht matchen # soll, wenn hinten oder vorne noch etwas steht (falls dem nicht so ist # kannst du die nächste Zeile einfach löschen): $rx = '\\A'. $rx .'\\z'; # Zuletzt wird $rx als regulärer Ausdruck zurückgegeben, sodass man ihn # auch wie einen benutzen kann ('irgendwas' =~ $rx): return qr/$rx/; } # mask2regex # irgendwo holst du dir die Maske her: my $mask = '*id*-datei.dat'; # dann erstellst du den regulären Ausdruck: my $regex = mask2regex($mask); # qr/(?-xism:\A\d+\-datei\.dat\z)/ # und testest die Dateinamen auf ihn: my @files = qw( -datei.dat 02-datei.dat 45-datei-dat 1-datei.dat.csv abc32-datei.dat ); print "$_\n" for grep $_ =~ $regex, @files; edit: Allerdings ist mir gerade aufgefallen, das pq's Lösung eleganter ist: Code (perl): (dl
)
1 2 3 my $regex = quotemeta $mask; $regex =~ s/\\\*(\w*)\\\*/$special{$1}/g; $regex = '\\A'. $regex .'\\z'; MfG Last edited: 2009-09-13 16:39:50 +0200 (CEST) perl -E'*==*",s;;%ENV=~m,..$,,$&+42;e,$==f;$"++for+ab..an;@"=qw,u t,,print+chr;sub f{split}say"@{=} me"'
|