RegEx

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
mechanicalStore
User
Beiträge: 172
Registriert: Dienstag 29. Dezember 2009, 00:09

Hallo Zusammen,

folgendes Programm

Code: Alles auswählen

import re

def main():
    test_string = "AB1234-5678-ABC"
    praefix = 'B'
    critical_area = '5678'

    pattern = re.compile("^(.{1})(.{1})(.{4})(.{1})(.{4})(.{4})$")

    regex_test = pattern.match(test_string)
    regex_results = [regex_test.group(x) for x in range(7)]
    print(regex_results)

if __name__ == '__main__':
    main()
erzeugt folgende Ausgabe, wie sie auch sein soll

Code: Alles auswählen

['AB1234-5678-ABC', 'A', 'B', '1234', '-', '5678', '-ABC']
Ich brauche die einzelnen Elemente, daher die Gruppierung. Ich will aber nicht nur die Anzahl der Stellen testen, sondern z.B. dass der praefix (bzw. z.B. auch critical_area) wirklich derjenige ist, also

Code: Alles auswählen

pattern = re.compile("^A({praefix})(.{1})(.{4})(.{1})({critical_area})(.{4})$")
was zu

Code: Alles auswählen

Traceback (most recent call last):
  File "/home/****/develop/test.py", line 15, in <module>
    main()
  File "/home/****/develop/test.py", line 11, in main
    regex_results = [regex_test.group(x) for x in range(7)]
                     ^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'group'
führt. Habe ich hier einen falschen Ansatz?
Benutzeravatar
sparrow
User
Beiträge: 4525
Registriert: Freitag 17. April 2009, 10:28

Ich empfehle zum Testen für regex immer regex101.com.
Das sieht an sich sich nicht richtig aus. Ich denke {praefix} macht nicht, was du denkst. Und das kann man dort gut nachvollziehen, weil im "Explanation"-Bereich steht, was dein Regex "bewirkt".

Was genau möchtest du denn testen? Daraus leitet sich ab, ob das überhaupt im Regex gemacht werden sollte oder hinterher im Code.

Ist das Format der Nummern immer gleich? Denn eigentlich sind Regex genau dafür da, so etwas zu prüfen. Das tust du aber gar nicht. Du gucks tob da eine bestimmte Anzahl von Zeichen kommt - welches ist dir aber egal.
Sirius3
User
Beiträge: 18250
Registriert: Sonntag 21. Oktober 2012, 17:20

Wenn Du Variablen in Strings haben willst, brauchst Du f-Strings:

Code: Alles auswählen

pattern = re.compile(f"^(A)({praefix})(.{{4}})(.)({critical_area})(.{{4}})$")
Wobei, der Code scheint ja recht spezifisch zu sein, Du matcht aber ganz allgemein.
Und Dinge, die eh fix sind, müssen nicht in Gruppen gepackt werden:

Code: Alles auswählen

pattern = re.compile(f"^A{praefix}([0-9]{{4}})-{critical_area}-([A-Z]{{3}})$")
Alternativ kann man aber auch einfach nachträglich Prüfen, ob die 3. Gruppe mit der cirtical_area übereinstimmt.
mechanicalStore
User
Beiträge: 172
Registriert: Dienstag 29. Dezember 2009, 00:09

@sparrow/@Sirius3

Danke für die Antworten. Da ich nicht weiter kam, hatte ich das erst mal rudimentär nur mit der Anzahl beliebiger Zeichen getestet.

Nochmal zu (er)Klärung: Das Muster ist immer gleich, die Zeichen/Zahlen selbst können jeweils anders sein. Aber nur ein Teil davon (praefix und cirtical_area) muss jeweils auf die Vorgabe matchen. Brauche aber alle Gruppen zur späteren Auswertung.

Das mit den Variablen hatte nicht funktioniert, keine Ahnung warum. Hatte das auch schon mit f-Strings probiert. Offenbar ein Typo meinerseits.

Jedenfalls funktioniert es jetzt. Danke euch beiden, auch für den Link auf regex101.com.
Antworten