/ / Drukowanie pierwszej instancji dopasowania w każdym wierszu pliku (Perl) - regex, perl

Drukowanie pierwszej instancji dopasowania w każdym wierszu pliku (Perl) - regex, perl

Mam następujący plik wykonywalny .pl:

#!/usr/bin/env perl
$file = "TfbG_peaks.txt";
open(INFO, $file) or die("Could not open file.");

foreach $line (<INFO>) {
if ($line =~ m/[^_]*(?=_)/){
#print $line; #this prints lines, which means there are matches
print $1; #but this prints nothing
}
}

Na podstawie mojego czytania w http://goo.gl/YlEN7 i http://goo.gl/VlwKe, print $1; powinien wydrukować pierwsze dopasowanie w każdym wierszu, ale tak nie jest.

Odpowiedzi:

2 dla odpowiedzi № 1

Nie, $1 powinien wydrukować ciąg zapisany przez tzw przechwytywanie grup (stworzony przez konstrukcję bracketingu - ( ... )). Na przykład:

if ($line =~ m/([^_]*)(?=_)/){
print $1;
# now this will print something,
# unless string begins from an underscore
# (which still matches the pattern, as * is read as "zero or more instances")
# are you sure you don"t need `+` here?
}

Wzór w oryginalnym kodzie nie zawierał żadnych grup przechwytywania, dlatego $1 był pusty (undef, precyzyjnie) tam. I (?=...) nie liczył się, ponieważ zostały one użyte do dodania podwyrażenia z wyprzedzeniem.


0 dla odpowiedzi nr 2

$1 drukuje, co pierwsze przechwycenie ((...)) we wziętym wzorze.

Może myślałeś o tym

print $& if $line =~ /[^_]*(?=_)/;    # BAD

lub

print ${^MATCH} if $line =~ /[^_]*(?=_)/p;   # 5.10+

Ale poniższe byłyby prostsze (i działały przed 5.10):

print $1 if $line =~ /([^_]*)_/;

Uwaga: Otrzymasz zwiększenie wydajności, gdy wzór nie pasuje, jeśli dodasz prowadzenie ^ lub (?:^|_) (cokolwiek jest odpowiednie).

print $1 if $line =~ /^([^_]*)_/;