2009-07-10 4 views
0

Ich versuche, einen Muster-Tester in Perl in-on-the-fly zu machen. Im Grunde fordert es Sie auf, das Muster einzugeben, und gibt Ihnen dann eine >>>> Eingabeaufforderung, wo Sie mögliche Übereinstimmungen eingeben. Wenn es übereinstimmt, sagt es "%%%% vor dem übereinstimmenden Teil nach der Übereinstimmung", und wenn nicht, sagt es "%%%! Zeichenfolge, die nicht übereinstimmte". Es ist trivial, wie dies zu tun:Auswertung eines benutzerdefinierten Regex von STDIN in Perl

while(<>){ 
    chomp; 
    if(/$pattern/){ 
     ... 
    } else { 
     ... 
    } 
} 

aber ich möchte in der Lage sein, das Muster wie /sometext/i eher geben als nur sometext Ich glaube, ich einen eval-Block dafür verwenden würde? Wie würde ich so etwas tun?

+0

Vielleicht sollten Sie nur Devel verwenden :: REPL stattdessen Ihre eigenen zu schreiben. – jrockway

+0

es ist Perl zu lernen, nicht für ein Projekt –

+0

Ich bin verwirrt: für den Zweck der Übung, warum _can't_ Sie einfach '/ $ pattern/i' verwenden? Vergessen Sie dabei nicht, dass Sie das Problem immer auf die andere Weise angehen können: Ändern Sie die Zeichenfolge, die Sie testen, ganz oben oder unten, anstatt die Übereinstimmung zu ändern. Dies ist oft nützlich, wenn einfache Benutzereingaben (Tippfehler) behandelt werden: Q oder q, QuiT, quIt usw. – Telemachus

Antwort

1

Dies klingt wie ein Job für Zeichenfolge eval, nur daran erinnern, nicht nicht vertrauenswürdige Strings zu bewerten. Hier

#!/usr/bin/perl 

use strict; 
use warnings; 

my $regex = <>; 
$regex = eval "qr$regex" or die [email protected]; 
while (<>) { 
    print /$regex/ ? "matched" : "didn't match", "\n"; 
} 

ist ein Beispiel Lauf:

perl x.pl 
/foo/i 
foo 
matched 
Foo 
matched 
bar 
didn't match 
^C 
+0

Wie würde das mit einer Ersetzung statt einer Übereinstimmung funktionieren? – radicalmatt

+0

Sie meinen, wenn der Benutzer die Zeichenfolge "s/foo/bar /" übergibt? In diesem Fall würde ich etwas wie 'my $ subst = <> sagen; while (<>) {eval $ subst oder die $ @; print} ', aber auch das ist sehr gefährlich. Was auch immer der Benutzer in der ersten Zeile eingibt, wird als Perl-Code ausgeführt. –

+0

Ich habe etwas ähnliches versucht - aber das Geplapper in der Substitution hat immer wieder versagt. – radicalmatt

-1

Dies funktioniert für mich:

my $foo = "My bonnie lies over the ocean"; 

print "Enter a pattern:\n"; 
while (<STDIN>) { 
    my $pattern = $_; 
    if (not ($pattern =~ /^\/.*\/[a-z]?$/)) { 
     print "Invalid pattern\n"; 
    } else { 
     my $x = eval "if (\$foo =~ $pattern) { return 1; } else { return 0; }"; 
     if ($x == 1) { 
     print "Pattern match\n"; 
     } else { 
     print "Not a pattern match\n"; 
     } 
    } 
    print "Enter a pattern:\n" 
} 
1

Sie /(?i:<pattern>)/ statt /<pattern>/i schreiben kann.