2011-07-15 22 views
5

Bir dosya satırında, herhangi bir regex kümesiyle eşleşip eşleşmediğini görmek istiyorum. BöylePerl regex'in hangi kısmının bir dizeyle eşleştirildiğini nasıl bilebilirim?

şey:

my @regs = (qr/a/, qr/b/, qr/c/); 
foreach my $line (<ARGV>) { 
    foreach my $reg (@regs) { 
     if ($line =~ /$reg/) { 
     printf("matched %s\n", $reg); 
     } 
    } 
} 

ama bu yavaş olabilir.

Bu regex derleyicisinin yardımcı olabileceği gibi görünüyor. Böyle bir optimizasyon var mı:

my $master_reg = join("|", @regs); # this is wrong syntax. what's the right way? 
foreach my $line (<ARGV>) { 
    $line =~ /$master_reg/; 
    my $matched = special_function(); 
    printf("matched the %sth reg: %s\n", $matched, $regs[$matched] 
} 

} 'special_function' regex kısmı denk getirilmiştir bana özel sosu olan

.

cevap

8

Yakalama parantezlerini kullanın.

my @matches = $foo =~ /(one)|(two)|(three)/; 
defined $matches[0] 
    and print "Matched 'one'\n"; 
defined $matches[1] 
    and print "Matched 'two'\n"; 
defined $matches[2] 
    and print "Matched 'three'\n"; 
5

Ekle yakalama grupları:: Temel fikir, şöyle sadece de /(a|b|c)/ kullanılan ve sadece $1 basılmış olabilirdi

"pear" =~ /(a)|(b)|(c)/; 
if (defined $1) { 
    print "Matched a\n"; 
} elsif (defined $2) { 
    print "Matched b\n"; 
} elsif (defined $3) { 
    print "Matched c\n"; 
} else { 
    print "No match\n"; 
} 

Açıkçası bu basit örnekte, ama ne zaman 'a', 'b 've' c 'keyfi olarak karmaşık ifadeler olabilir, bu bir kazançtır.

Eğer regex kadar bina ediyorsanız programlı ağrı verici numaralı değişkenleri kullanmak zorunda bulabilir, böylece yerine katılığına kırma, her maç pozisyon için uzaklıklar ihtiva yerine @- veya @+ diziler, bakın. $-[0] her zaman desen eşleştiği sürece ayarlanır, ancak daha yüksek $-[$n] yalnızca n yakalama grubu eşleştiğinde tanımlı değerler içerir.

İlgili konular