In einem regulären Python-Ausdruck stoße ich auf dieses singuläre Problem. Könnten Sie Anweisungen zu den Unterschieden zwischen re.findall('(ab|cd)', string)
und geben re.findall('(ab|cd)+', string)
?
import re
string = 'abcdla'
result = re.findall('(ab|cd)', string)
result2 = re.findall('(ab|cd)+', string)
print(result)
print(result2)
Die tatsächliche Ausgabe ist:
['ab', 'cd']
['cd']
Ich bin verwirrt, warum das zweite Ergebnis nicht 'ab'
so gut enthält.
Antworten:
+
ist ein Wiederholungsquantifizierer, der ein- oder mehrmals übereinstimmt. In der Regex(ab|cd)+
werden Sie Wiederholung der Capture - Gruppe(ab|cd)
+ mit. Dadurch wird nur die letzte Iteration erfasst.Sie können über dieses Verhalten wie folgt argumentieren:
Angenommen, Ihre Zeichenfolge ist
abcdla
und Regex ist(ab|cd)+
. Die Regex-Engine findet eine Übereinstimmung für die Gruppe zwischen den Positionen 0 und 1 alsab
und verlässt die Erfassungsgruppe. Dann sieht es den+
Quantifizierer und versucht so, die Gruppe erneut zu erfassen und wirdcd
zwischen den Positionen 2 und 3 erfassen .Wenn Sie alle Iterationen erfassen möchten, sollten Sie stattdessen die sich wiederholende Gruppe erfassen, mit
((ab|cd)+)
derabcd
und übereinstimmtcd
. Sie können die innere Gruppe nicht erfassen, da es uns egal ist, mit((?:ab|cd)+)
welchen Übereinstimmungen die innere Gruppe übereinstimmtabcd
https://www.regular-expressions.info/captureall.html
Aus den Dokumenten,
quelle
'(?:ab|cd)+'
Wird einfach funktionieren.Ich weiß nicht, ob dies die Dinge mehr klären wird, aber versuchen wir uns auf einfache Weise vorzustellen, was unter der Haube passiert. Wir werden zusammenfassen, was mit Match passiert
findall
Passen Sie den String an und verbrauchen Sie ihn gleichzeitig. Stellen wir uns vor, was mit diesem REGEX passiert'(ab|cd)'
:Jetzt das gleiche mit
'(ab|cd)+'
Ich hoffe das klärt die Sache ein bisschen.
quelle
Für mich war der verwirrende Teil die Tatsache, dass
docs
Sie erhalten also keine vollständige Übereinstimmung, sondern nur eine Übereinstimmung eines Captures. Wenn Sie diese Gruppe nicht erfassen lassen
(re.findall('(?:ab|cd)+', string)
, wird sie["abcd"]
wie ursprünglich erwartet zurückgegebenquelle