Warum ergibt xx etwas anderes als x {2} ? Bitte schauen Sie sich das folgende Beispiel an:
import re
lines = re.findall(r'".*?"".*?"', '"x""y"')
print(lines) # yields: ['"x""y"']
lines = re.findall(r'(".*?"){2}', '"x""y"')
print(lines) # yields: ['"y"']
4 Antworten
Gemäß der Dokumentation von findall
, wenn Wenn Sie eine Gruppe im regulären Ausdruck haben, wird die Liste dieser Gruppen zurückgegeben, entweder als Tupel für 2+ Gruppen oder als Zeichenfolge für 1 Gruppe. In Ihrem Fall sind Ihre beiden regulären Ausdrücke nicht nur xx
gegenüber x{2}
, sondern der zweite ist (x){2}
, der eine Gruppe hat, wenn der erste reguläre Ausdruck keine Gruppen hat.
Daher stimmt "x"
beim ersten Mal mit der Gruppe überein, dann "y"
beim zweiten Mal mit der Gruppe. Dies erfüllt Ihre allgemeine Regex, aber "y"
überschreibt "x"
für den Wert von Gruppe 1.
Der einfachste Weg, dies in Ihrem Beispiel zu lösen, besteht darin, Ihre Gruppe in eine nicht übereinstimmende Gruppe zu konvertieren: (?:".*?"){2}
. Wenn Sie zwei Gruppen möchten, eine für "x"
und eine für "y"
, müssen Sie die Gruppe zweimal wiederholen: (".*?")(".*?")
. Sie können möglicherweise benannte Gruppen verwenden, um diese Wiederholung zu vereinfachen.
AFAIK, findall()
ist capture group first
. Wenn die angewendete Regex eine Erfassungsgruppe enthält, gibt findall()
nur Erfassungsgruppenwerte zurück.
Und nur wenn die angewendete Regex keine Erfassungsgruppe enthält, gibt findall()
fullmatch values
zurück.
Wenn Sie also findall()
fullmatch value
zurückgeben möchten, dürfen Sie die Erfassungsgruppe im regulären Ausdruck nicht wie folgt verwenden
(?:".*?"){2}
In denen (?:
... )
non-capture group
angeben.
Also in Python
print(re.findall(r'(?:".*?"){2}', '"x""y"'))
Der erste Ausdruck ist "X und dann Y, wobei Y versehentlich mit X" übereinstimmt.
Der zweite Ausdruck ist "(X) {zweimal wiederholen}" . Gruppe 1 darf nicht XX enthalten, da Gruppe 1 nicht mit XX übereinstimmt. Es passt zu X.
Mit anderen Worten: Der Gruppeninhalt ändert sich nicht nur aufgrund eines Quantifizierers außerhalb der Gruppe.
Eine Möglichkeit, den zweiten Ausdruck zu beheben, besteht darin, eine äußere Gruppe zu bilden (und die innere Gruppe nicht zu erfassen).
lines = re.findall(r'((?:".*?"){2})', '"x""y"')
Über Ihr zweites Muster (".*?"){2}
:
Ein Zitat aus den Übereinstimmungsregeln
Wenn eine Gruppe in einem Teil des Musters enthalten ist, der mehrfach übereinstimmt, wird die letzte Übereinstimmung zurückgegeben.
Und findall führt Folgendes aus:
Wenn eine oder mehrere Gruppen im Muster vorhanden sind, geben Sie eine Liste der Gruppen zurück.
Ihr Muster (".*?"){2}
bedeutet, dass (".*?")
zweimal hintereinander übereinstimmen sollte und gemäß der ersten Regel nur der Inhalt der letzten Übereinstimmung erfasst wird.
Für Ihre Daten findet findall
die Sequenz (".*?"){2}
nur einmal, sodass eine Liste zurückgegeben wird, die aus der zuletzt erfassten Gruppe für eine einzelne Übereinstimmung besteht: ['"y"']
.
Dieses Beispiel würde es offensichtlicher machen:
import re
print (re.findall(r'(\d){2}', 'a12b34c56'))
# ['2', '4', '6']
Sie können sehen, dass findall die Sequenz (\d){2}
dreimal findet und für jede den zuletzt erfassten Inhalt für die Gruppe (\d)
zurückgibt.
Nun zu Ihrem ersten Muster: ".*?"".*?"
.
Diese enthält keine Untergruppen und laut findall In diesem Fall wird erneut Folgendes zurückgegeben:
Alle nicht überlappenden Übereinstimmungen von Mustern in Zeichenfolgen als Liste von Zeichenfolgen.
Für Ihre Daten ist es also ['"x""y"']
.
Verwandte Fragen
Neue Fragen
python
Python ist eine dynamisch typisierte Mehrzweck-Programmiersprache mit mehreren Paradigmen. Es wurde entwickelt, um schnell zu lernen, zu verstehen, zu verwenden und eine saubere und einheitliche Syntax durchzusetzen. Bitte beachten Sie, dass Python 2 ab dem 01.01.2020 offiziell nicht mehr unterstützt wird. Fügen Sie für versionenspezifische Python-Fragen das Tag [python-2.7] oder [python-3.x] hinzu. Wenn Sie eine Python-Variante (z. B. Jython, PyPy) oder eine Bibliothek (z. B. Pandas und NumPy) verwenden, fügen Sie diese bitte in die Tags ein.