2010-10-21 7 views
10

Wenn ich

"Year 2010" =~ /([0-4]*)/; 
print $1; 

laufen bekomme ich leere Zeichenkette. Aber

"Year 2010" =~ /([0-4]+)/; 
print $1; 

Ausgänge "2010". Warum?

+0

Was seltsam ist, ist, dass '/ \ s ([0-4] *) /' nicht das gleiche Shortcut-Verhalten hat. Es heißt nicht "Ich habe die Null-Länge-Zeichenfolge am Ende des Raumes, hier gehst du." – Axeman

+0

@Axeman, das ist, weil '*' gierig ist. Die Ziffern sind da, also packt sie sie. Wenn Sie mit "The Year 2010" übereinstimmen, ist "$ 1" die Zeichenfolge mit der Länge Null nach dem ersten Leerzeichen. – cjm

Antwort

19

Sie erhalten ein leeres Match gleich zu Beginn des Strings "Jahr 2010" für das erste Formular, weil das * sofort 0 Ziffern entspricht. Das + Formular muss warten, bis es mindestens eine Ziffer sieht, bevor es übereinstimmt.

Vermutlich, wenn Sie durch alle die Spiele der ersten Form gehen, werden Sie schließlich 2010 finden ... aber wahrscheinlich erst, nachdem es findet eine weiteres leeres Spiel vor dem ‚e‘, dann, bevor die ‚a‘ usw.

+0

Großartig, danke! – alexanderkuk

+0

Kleen Stern-generierte Obermenge enthält auch leere Zeichenfolge, also ja, es wird leere Zeichenfolge vor Y, e, a, r, Leerzeichen, und dann wird es 2010 finden. –

5

Die erste entspricht der Nulllänge am Anfang (vor Y) und gibt sie zurück. Die zweite sucht nach einer oder mehreren Ziffern und wartet, bis sie 2010 findet.

6

Der erste reguläre Ausdruck stimmt mit null Ziffern am Anfang der Zeichenfolge überein, was zur Erfassung der leeren Zeichenfolge führt.

Der zweite reguläre Ausdruck nicht zu Beginn der Zeichenfolge übereinstimmen, aber es passt, wenn es 2010

5

erreicht man auch YAPE::Regex::Explain zur Erläuterung eines regulären Ausdrucks wie

use YAPE::Regex::Explain; 

print YAPE::Regex::Explain->new('([0-4]*)')->explain(); 
print YAPE::Regex::Explain->new('([0-4]+)')->explain(); 

verwenden können Ausgang:

The regular expression: 
(?-imsx:([0-4]*)) 
matches as follows: 

NODE      EXPLANATION 
---------------------------------------------------------------------- 
(?-imsx:     group, but do not capture (case-sensitive) 
         (with^and $ matching normally) (with . not 
         matching \n) (matching whitespace and # 
         normally): 
---------------------------------------------------------------------- 
    (      group and capture to \1: 
---------------------------------------------------------------------- 
    [0-4]*     any character of: '0' to '4' (0 or more 
          times (matching the most amount 
          possible)) 
---------------------------------------------------------------------- 
)      end of \1 
---------------------------------------------------------------------- 
)      end of grouping 
---------------------------------------------------------------------- 

The regular expression: 
(?-imsx:([0-4]+)) 
matches as follows: 

NODE      EXPLANATION 
---------------------------------------------------------------------- 
(?-imsx:     group, but do not capture (case-sensitive) 
         (with^and $ matching normally) (with . not 
         matching \n) (matching whitespace and # 
         normally): 
---------------------------------------------------------------------- 
    (      group and capture to \1: 
---------------------------------------------------------------------- 
    [0-4]+     any character of: '0' to '4' (1 or more 
          times (matching the most amount 
          possible)) 
---------------------------------------------------------------------- 
)      end of \1 
---------------------------------------------------------------------- 
)      end of grouping 
---------------------------------------------------------------------- 
1

das Sternsymbol im Grunde versucht, 0 oder mehr Symbole in gegebenem Satz (in der Theorie übereinstimmen, die Menge {x, y} * besteht der leere String und alle möglichen endlichen Sequenzen aus x und y), und daher wird es genau Null Zeichen (leere Zeichenfolge) am Anfang der Zeichenfolge, null Zeichen nach dem ersten Zeichen, Null Zeichen nach dem zweiten Zeichen usw. Dann wird es endlich 2 finden und mit ganzem 2010 übereinstimmen.

Das Plussymbol passt zu einem oder mehreren Zeichen aus der gegebenen Menge ({x, y} + besteht aus allen möglichen endlichen Folgen aus x und y, ohne die leere Zeichenkette) , im Gegensatz zu {x, y} *). Also ist das erste übereinstimmende Zeichen 2, dann next - 0 wird geprüft, dann 1, dann noch eine 0, und dann endet der Satz, so dass die gefundene Gruppe wie "2010" aussieht.

Es ist Standardverhalten für reguläre Ausdrücke, definiert in der formalen Sprachtheorie. Ich empfehle eine wenig Theorie über reguläre Ausdrücke zu lernen, kann es nicht schaden, kann aber :)

0

Um Ihr erstes RE Spiel zu machen, verwenden Sie den Anker ‚$‘ helfen:

"Year 2010" =~ /([0-4]*)$/; 
print $1; 
1

Wir haben dies als eine Trickfrage in Learning Perl. Jede Regex, die mit null Zeichen übereinstimmen kann, die nicht am Anfang der Zeichenfolge übereinstimmen, entspricht null Zeichen.

Die Perl-Regex-Engine stimmt mit der am weitesten links stehenden Übereinstimmung überein, wobei der Teil ganz links an erster Stelle steht.Nicht alle Regex-Engines funktionieren jedoch so. Wenn Sie alle technischen Details wünschen, lesen Sie Reguläre Ausdrücke beherrschen, was erklärt, wie Regex-Engines funktionieren und Übereinstimmungen finden.

Verwandte Themen