/ / Python3: Untergruppenübereinstimmungen funktionieren nicht für OR '|' verband reguläre Ausdrücke - Regex, Python-3.x

Python3: Untergruppenübereinstimmungen funktionieren nicht für OR '|' verband reguläre Ausdrücke - Regex, Python-3.x

Ich versuche, einige Zeilen aus einer CSV-Datei zu analysieren, um eine Reihe von Ziffern zu extrahieren. Es gibt zwei mögliche Formate, die Ziffern allein oder die Ziffern, die in einen längeren Code eingebettet sind.

Hier ist ein Codebeispiel für das, was ich mache und was falsch läuft:

# regex works
>>> re.search("^(d+)$", "5755").group(0, 1)
("5755", "5755")

# regex works with capturing group inside non-capturing group
>>> re.search("(?:^(d+)$)", "5755").group(0, 1)
("5755", "5755")

# regex does not work as second of two non-capturing groups
>>> re.search("(?:$SK-*(d+)[-K])|(?:^(d+)$)", "5755").group(0, 1)
("5755", None)

# the other regex of the pair works
>>> re.search("(?:$SK-*(d+)[-K])|(?:^(d+)$)", "11$SK-2301-K13").group(0, 1)
("$SK-2301-", "2301")

# the regex works as the first of two non-capturing groups
>>> re.search("(?:^(d+)$)|(?:$SK-*(d+)[-K])", "5755").group(0, 1)
("5755", "5755")

Wie Sie sehen können, funktioniert der reguläre Ausdruck gutallein oder in eine (? ...) verpackt, aber wenn mit einem anderen Regex kombiniert, hört die Gruppe der zweiten der beiden Regex "s funktioniert, obwohl die Suche ein Match-Objekt zurückgibt. Allerdings, wenn ich dann tauschen die Reihenfolge der Regex "s zusammen, die erste wird immer noch unabhängig davon, welche Regex es ist.

Um es klar zu sagen, wenn ich zwei funktionierende Regexs zusammen mit einer Pipe ("|") kombiniere, funktionieren die Gruppen auf der ersten, aber die auf der zweiten nicht.

Warum passiert dies? Wie kann ich das beheben?

Antworten:

1 für die Antwort № 1

Die Ursache des Problems liegt darin, dass ein intuitives Verständnis der Funktionsweise der Untergruppen nicht in der Praxis funktioniert.

Ich werde auf das, was zwei verschiedene Kommentare auf Ihre Frage richtig hinweisen, erweitern. Untergruppen werden nicht so nummeriert, wie sie erfasst werden, sondern werden bei der Erstellung / Analyse der Regex festgelegt. Beispielsweise:

re.search("match:(foo)","match:foo").group(1)

Wird sein

("foo")

Weil die erste Erfassungsgruppe ist (foo). Ähnlich

re.search("match:(foo)(bar)","match:foobar").group(1,2)

Wird sein

("foo","bar")

Als erste und zweite Fanggruppe sind (foo) und (bar) und jeder abgestimmt und gefangen.

In einem Muster wie

match:(?:(foo)|(bar))

(foo) und (bar) sind immer noch die erste und zweite Fanggruppe, auch wenn nur einer von ihnen möglicherweise dank der OR erfassen kann |.

re.search("match:(?:(foo)|(bar))","match:foo").group(1,2)
re.search("match:(?:(foo)|(bar))","match:bar").group(1,2)

Wird ausgegeben

("foo", None)
(None, "bar")

Daher müssen Sie Ihrem Code Logik hinzufügen, um zu prüfen, welche der Erfassungsgruppen über Inhalt verfügt, und diesen zurückgeben.