2016-04-02 6 views
25

In den folgenden Beispielen (über regex101.com, PCRE-Modus) kann ich nicht herausfinden, warum der + Quantifizierer einen Teilstring findet, aber * nicht.Warum passt * nicht zu +?

In der ersten Abbildung, die + Quantifizierer (1 oder mehr) findet alle vier Klein ein Zeichen (das ist das, was ich erwartet):

Plus-sign quantifier finds 1 or more as expected

In der zweiten Abbildung, die * quantifier (0 oder mehr) findet keinen Klein ein Zeichen (was ich nicht erwartet, was ist):

Asterisk quantifier doesn't find 0 or more

Was REGEX Logik erklärt, warum "1 oder mehr" (+) findet alle vier Kleinbuchstaben ein Zeichen, aber "0 oder mehr" (*) findet keine?

Antwort

45

Die Regex-Engine versucht, das gesamte Muster an jeder Position in der Zeichenfolge von links nach rechts abzugleichen. Das Muster /a*/ stimmt erfolgreich mit der Null a s am Anfang der Zeichenfolge überein. Dies ist, was das kleine gepunktete Caret in Ihrem Regex101-Screenshot bedeutet - eine Null-Breite-Übereinstimmung an dieser Position. Es würde mehr a s an dieser Position entsprechen, aber es gibt keine. Trotzdem ist das Spiel erfolgreich.

Wenn Sie eine Funktion verwenden, die alle Regex-Übereinstimmungen in der Zeichenfolge zurückgibt, wird sie jedes Mal um mindestens ein Zeichen nach neuen Übereinstimmungen suchen zu ihm. Beispiel in Python:

import re 
regex = r"a*" 
input = "AAAAaaaaBBBBbbbb" 
print(re.findall(regex, input)) 

Ausgang:

['', '', '', '', 'aaaa', '', '', '', '', '', '', '', '', ''] 

Während, wenn Sie /a+/ verwenden, ist es nicht, diese Null-Breite Matches tun kann, so dass es durch die Eingangsstufe, bis er sein erstes findet und passen Sie nur bei .

+0

Es ist seltsam, dass es standardmäßig nicht gierig ist, oder ist dies die Konvention? In Sublime stimmt es mit dem ganzen aaaa überein, es sei denn, du machst ein *? dann verhält es sich so. –

+12

Gierig oder nicht, 'a *' stimmt mit dem Nullvorkommen von 'a' am Anfang des Strings überein, warum sollte der Parser also weiter schauen? Ich weiß nicht, was "Sublime" ist, aber es klingt gebrochen. – ghoti

+0

@Ghoti es ist ein Windows-Texteditor/IDE wie Notepad ++ (aber es ist 100% kostenlos wie NP ++ ist) ... aber es klingt für mich auch gebrochen: P. – RastaJedi

7

Es entspricht tatsächlich dem Anfang der Zeichenfolge, wo Null A sind. Wenn Sie mit einem String beginnen, wird es mit allen übereinstimmen.

9

Andere Antworten beschreiben bereits, was vor sich geht. Aber für eine Illustration/Beispiel, versuchen Sie dies für Größe:

$ echo AAAAaaaabbbb | egrep -o 'a*' && echo "SUCCESS" 

SUCCESS 

Die Wirkung von -o Option des grep ist es, Ihnen zu zeigen, nur den Teil des Eingangs an, die regex abgestimmt. Da passierte passierte "Null-Zeichen", das Ergebnis ist leer ... aber erfolgreich.

+2

Aus welchem ​​Grund auch immer, als ich das (über Kopieren und Einfügen) auf Mint Linux 17.3 versuchte, zeigte egrep "aaaa" über dem Wort SUCCESS – RBV

+1

@RBV - interessant .. und unerwartet. Ich sehe dieses Verhalten nicht in BSD grep (basierend auf GNU grep Version 2.5.1) in FreeBSD oder OSX, aber ich kann ein ähnliches Verhalten wie in GNU grep 2.5.4 in Ubuntu feststellen. Ich kann diese Inkonsistenz zwischen verschiedenen GNU-Greps nicht erklären. Wenn Sie nach "z *" suchen, sehen Sie auch ERFOLG. – ghoti

+0

"aber ich kann ähnliches Verhalten bestätigen ..." Was in meinem Kopf die Frage aufwirft, welche Varianten von egrep man "vertrauen" kann oder nicht, um vorhersagbar zu sein. – RBV

3

Am Anfang können Sie das Spiel sehen!

What