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"']
1
user9611000 18 Apr. 2018 im 00:23

4 Antworten

Beste Antwort

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.

0
scnerd 17 Apr. 2018 im 21:44

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"'))
0
Thm Lee 18 Apr. 2018 im 05:14

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"')
0
Tomalak 17 Apr. 2018 im 21:59

Ü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"'].

0
wolfrevokcats 17 Apr. 2018 im 22:18