Verschiedene Datum-Formate aus einen Text extrahieren

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
phischmi
User
Beiträge: 34
Registriert: Dienstag 12. Juli 2016, 06:08

Hallo zusammen,

ich stehe vor einem Problem, für das ich leider noch keine passende Lösung gefunden habe.

Ich habe Textblöcke, welche ein Datum in unterschiedlichsten Formaten enthalten können.

1009
10.09.
10.09.2021
100921
10092021
100921 08-15 Uhr
1009210815

usw.

Ich benötige also eine Funktion, in welcher ich möglichst einfach selbst definiere kann, nach welchen Formaten gesucht werden soll.
Bisher habe ich verschiedene Lösungen wie dateutil.parser, dateparser oder datefinder ausprobiert, bin jedoch immer daran gescheitert, dass die Formate teilweise nicht oder falsch erkannt werden.
Wie könnte ich dieses Problem lösen?

VG Philipp
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@phischmi: Schau Dir das `re` (oder externe `regex`) Modul an. Und es kann sein, dass Du auf Datumsangaben triffst, die sich nicht eindeutig erkennen lassen. Ist 100921 der 21.09.2010 oder der 10.09.2021 oder der 09.10.2021? Oder jeweils 1921 statt 2021?
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
phischmi
User
Beiträge: 34
Registriert: Dienstag 12. Juli 2016, 06:08

@__blackjack__
Vielen Dank für deine Rückmeldung. Hatte auch schon vermutet, dass die Formate so speziell sind, dass ich wohl den Weg über regular expressions und strptime() gehen muss. Die Datumswerte sind zum Glück immer so aufgebaut, dass dass Jahr hinten steht und immer 2021 gemeint ist.
Wie kann ich mit re am besten in einem Durchgang auf verschiedene Muster prüfen und dann mit strptime() aus den gefundenen String das passende Datum generieren?

VG Philipp
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

Der reguläre Ausdruck ist doch ganz simple, zwei Zahlen, dann optional ein Punkt, dann zwei Zahlen, dann optional ein Punkt, dann entweder 2 oder 4 Zahlen.
phischmi
User
Beiträge: 34
Registriert: Dienstag 12. Juli 2016, 06:08

Ist für mich leider nicht ganz so simpel, da ich mich mit RegEx in Python bisher nicht auseinander gesetzt habe :/
Also genügt ein Muster aus, um alle möglichen Formate abzugreifen? Die Umwandlung in ein Datum erfolgt dann mit strptime() unabhängig von der extrahierten Zeichenfolge?
rogerb
User
Beiträge: 878
Registriert: Dienstag 26. November 2019, 23:24

@phischmi,

Die das Formattemplate von strptime() ist sehr "streng" und erwartet, dass die Monatsangabe zum Beispiel immer an der gleichen Stelle steht und dass es immer die gleiche Anzahl von Ziffern sind.
Daher wurde dir ja schon die flexiblere und mächtigere Vorgehensweise mit regulären Ausdrücken vorgeschlagen.
Was weißt du denn von diesen Zahlenkolonnen?
Was kommt zuerst? Tag oder Monat?
Bestehen die Monats und Tageszahlen, wie hier immer, aus zwei Ziffern?
Gibt es außer "." vielleicht noch andere Trennzeichen zwischen den Zahlen?
Usw.
Je mehr man als sicher gegeben voraussetzen kann, um so einfacher ist die Programmierung

Ein Beispiel, welches noch nicht alle Fälle abdeckt und natürlich auf bestimmten Annahmen beruht. Das muss man jetzt noch verfeinern.

Code: Alles auswählen

import re

REGEX = re.compile(r"(\d{2}).?(\d{2}).?(\d{2,4})")

TEST_STRINGS = [
    r"10+09+2021",
    r"10-09-2021",
    r"10\09/2021",
    r"10.09.2021",
    r"10.09.21",
]


def expand_date(date_string):
    result = re.match(REGEX, date_string)
    return result.groups()


def main():
    for test_string in TEST_STRINGS:
        day, month, year = expand_date(test_string)
        if len(year) == 2:
            year = f"20{year}"
        print(f"Tag: {day}, Monat: {month}, Jahr: {year}")


if __name__ == "__main__":
    main()

"""
Ausgabe
Tag: 10, Monat: 09, Jahr: 2021
Tag: 10, Monat: 09, Jahr: 2021
Tag: 10, Monat: 09, Jahr: 2021
Tag: 10, Monat: 09, Jahr: 2021
Tag: 10, Monat: 09, Jahr: 2021
"""
Benutzeravatar
noisefloor
User
Beiträge: 3843
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

@phischmi: was ich zum rumprobieren mit regulären Ausdrücken immer ganz praktisch finde ist die Seite https://regex101.com/ . Da wird einem interaktiv direkt ein Ergebnis angezeigt und der Ausdruck auch erklärt. Zum rumtesten ist die Seite IMHO einfacher, als jedes mal das Skript zu ändern und neu laufen zu lassen.
Wichtig: links auf der Seite beim Punkt "flavor" "Python" auswählen.

Gruß, noisefloor
phischmi
User
Beiträge: 34
Registriert: Dienstag 12. Juli 2016, 06:08

Hallo zusammen,

vielen Dank für eure Tipps! Damit habt ihr mir schon sehr weiter geholfen! :)

Vielen Grüße und eine guten Wochenstart.

Philipp
Antworten