Nur ein Hinweis: Es beginnt und endet mit einer Ziffer. Lass mich darüber nachdenken. Obwohl Regex dort dein Freund sein kann.
Hamish Grubijan
Antworten:
79
Wenn das Datum in einer festen Form angegeben ist, können Sie einfach einen regulären Ausdruck verwenden, um das Datum zu extrahieren, und "datetime.datetime.strptime", um das Datum zu analysieren:
import re
from datetime import datetime
match = re.search(r'\d{4}-\d{2}-\d{2}', text)
date = datetime.strptime(match.group(), '%Y-%m-%d').date()
Andernfalls können Sie das Datum nicht einfach extrahieren, wenn es in einer beliebigen Form angegeben wird.
Was ist, wenn es im europäischen Format vorliegt, z. B. 20/01/1980, was "20. Januar 1980" bedeutet? Was ist, wenn Monate / Tage / Jahre außerhalb des angemessenen Bereichs liegen?
Hamish Grubijan
@lunaryorn Bezieht sich "re" in der ersten Anweisung auf die Zeichenfolge, in der wir nach unserem gewünschten Muster suchen?
Vishal
@ vishal.k Es bezieht sich auf das eingebaute reModul, dh , import re.
Mondhorn
Für den Fall, dass jemand anderes den gleichen Fehler gemacht hat: Sie müssen from datetime import datetimestattimport datetime
In [1]: import dateutil.parser as dparser
In [18]: dparser.parse("monkey 2010-07-10 love banana",fuzzy=True)
Out[18]: datetime.datetime(2010, 7, 10, 0, 0)
Ungültige Daten führen zu einem ValueError:
In [19]: dparser.parse("monkey 2010-07-32 love banana",fuzzy=True)
# ValueError: day is out of range for month
Es kann Daten in vielen Formaten erkennen:
In [20]: dparser.parse("monkey 20/01/1980 love banana",fuzzy=True)
Out[20]: datetime.datetime(1980, 1, 20, 0, 0)
Beachten Sie, dass es eine Vermutung gibt, wenn das Datum nicht eindeutig ist:
In [23]: dparser.parse("monkey 10/01/1980 love banana",fuzzy=True)
Out[23]: datetime.datetime(1980, 10, 1, 0, 0)
Die Art und Weise, wie mehrdeutige Daten analysiert werden, ist jedoch anpassbar:
In [21]: dparser.parse("monkey 10/01/1980 love banana",fuzzy=True, dayfirst=True)
Out[21]: datetime.datetime(1980, 1, 10, 0, 0)
@Hamish: Wenn es zwei Datumsangaben gibt (wie im Fall von "monkey 10/01/1980 love 7/10/2010 banana"), wird möglicherweise ein ValueError ausgelöst, oder (wie im Fall von "monkey 10/01/1980 love 2010-07-10 banana") wird das zweite Datum möglicherweise falsch interpretiert, indem Stunden, Minuten, Sekunden oder Zeitzonen angegeben werden. fuzzy=Truegibt es Lizenz zu raten.
Unutbu
1
@unutbu str = "Von flufie · 14. Oktober 2010 um 23:22 Uhr · 26 Antworten" Durch die Verwendung von dateutil erhalte ich "ValueError: Stunde muss in 0..23 sein"
saravanan
Was passiert, wenn der Text mehr als ein Datum enthält?
Alvas
1
@alvas: Die parseFunktion kann eine Ausnahme auslösen (auch wenn fuzzy=True) oder mit fuzzy=True, dass sie das erste Datum oder einen Mischmasch zurückgibt, der aus Teilen beider Daten besteht. Also wirklich, parsesollte nur für eine Zeichenfolge aufgerufen werden, die ein Datum enthält.
Unutbu
1
@Kailegh: Ja, es wäre möglich, die Indizes mit fuzzy_with_tokens = True abzuleiten . Wenn Sie mehr Klarheit wünschen, beginnen Sie bitte eine neue Frage.
Unutbu
26
Zum Extrahieren des Datums aus einer Zeichenfolge in Python; Das beste verfügbare Modul ist das Datefinder- Modul.
Sie können es in Ihrem Python-Projekt verwenden, indem Sie die folgenden einfachen Schritte ausführen.
Schritt 1: Installieren Sie das Datefinder-Paket
pip install datefinder
Schritt 2: Verwenden Sie es in Ihrem Projekt
import datefinder
input_string = "monkey 2010-07-10 love banana"# a generator will be returned by the datefinder module. I'm typecasting it to a list. Please read the note of caution provided at the bottom.
matches = list(datefinder.find_dates(input_string))
if len(matches) > 0:
# date returned will be a datetime.datetime object. here we are only using the first match.
date = matches[0]
print date
else:
print'No dates found'
Hinweis: Wenn Sie eine große Anzahl von Übereinstimmungen erwarten; Dann wird die Typumwandlung in eine Liste nicht empfohlen, da dies einen hohen Leistungsaufwand bedeutet.
Ich fand, dass datefinderdie mehrdeutige python-dateutilDatumsübereinstimmung besser war, als nur zwei mögliche Daten aus einem zufälligen Medium.com-Blog-Beitrag zurückzugeben, anstatt fünf. Ich
bin
Dies ist ziemlich gut, außer dass es irgendwie nicht funktioniert, wenn es einen Doppelpunkt (:) vor Datumszeichenfolge gibt: string = "Assessment Date: 17-May-2017 at 13:31"list(datefinder.find_dates(string.lower()))#[]string = "Assessment Date 17-May-2017 at 13:31"list(datefinder.find_dates(string.lower()))#[datetime.datetime(2017, 5, 17, 13, 31)]
Narahari BM
Ich bin damit einverstanden, dass der Datumsfinder für mehrdeutigen Text viel besser ist als der Dateparser
Jay Jung,
2
Mit Pygrok können Sie abstrahierte Erweiterungen der Syntax für reguläre Ausdrücke definieren.
Die benutzerdefinierten Muster können im Format in Ihre Regex aufgenommen werden %{PATTERN_NAME}.
Sie können auch eine Beschriftung für dieses Muster erstellen, indem Sie durch einen Doppelpunkt trennen : %s{PATTERN_NAME:matched_string}. Wenn das Muster übereinstimmt, wird der Wert als Teil des resultierenden Wörterbuch zurückgeführt wird (zB result.get('matched_string'))
Zum Beispiel:
from pygrok import Grok
input_string = 'monkey 2010-07-10 love banana'
date_pattern = '%{YEAR:year}-%{MONTHNUM:month}-%{MONTHDAY:day}'
grok = Grok(date_pattern)
print(grok.match(input_string))
Der resultierende Wert ist ein Wörterbuch:
{'month': '07', 'day': '10', 'year': '2010'}
Wenn das Datumsmuster nicht in der Eingabezeichenfolge vorhanden ist, lautet der Rückgabewert None. Wenn Ihr Muster hingegen keine Beschriftungen enthält, wird ein leeres Wörterbuch zurückgegeben{}
Sie können auch das Dateparser- Modul ausprobieren , das bei freiem Text möglicherweise langsamer als der Datefinder ist, jedoch mehr potenzielle Fälle und Datumsformate sowie eine erhebliche Anzahl von Sprachen abdecken sollte.
Wenn Sie die Position des Datumsobjekts in der Zeichenfolge kennen (z. B. in einer Protokolldatei), können Sie das Datum mit .split () [index] extrahieren, ohne das Format vollständig zu kennen.
Zum Beispiel:
>>> string = 'monkey 2010-07-10 love banana'>>> date = string.split()[1]
>>> date
'2010-07-10'
Antworten:
Wenn das Datum in einer festen Form angegeben ist, können Sie einfach einen regulären Ausdruck verwenden, um das Datum zu extrahieren, und "datetime.datetime.strptime", um das Datum zu analysieren:
import re from datetime import datetime match = re.search(r'\d{4}-\d{2}-\d{2}', text) date = datetime.strptime(match.group(), '%Y-%m-%d').date()
Andernfalls können Sie das Datum nicht einfach extrahieren, wenn es in einer beliebigen Form angegeben wird.
quelle
re
Modul, dh ,import re
.from datetime import datetime
stattimport datetime
Verwenden von Python-Dateutil :
In [1]: import dateutil.parser as dparser In [18]: dparser.parse("monkey 2010-07-10 love banana",fuzzy=True) Out[18]: datetime.datetime(2010, 7, 10, 0, 0)
Ungültige Daten führen zu einem
ValueError
:In [19]: dparser.parse("monkey 2010-07-32 love banana",fuzzy=True) # ValueError: day is out of range for month
Es kann Daten in vielen Formaten erkennen:
In [20]: dparser.parse("monkey 20/01/1980 love banana",fuzzy=True) Out[20]: datetime.datetime(1980, 1, 20, 0, 0)
Beachten Sie, dass es eine Vermutung gibt, wenn das Datum nicht eindeutig ist:
In [23]: dparser.parse("monkey 10/01/1980 love banana",fuzzy=True) Out[23]: datetime.datetime(1980, 10, 1, 0, 0)
Die Art und Weise, wie mehrdeutige Daten analysiert werden, ist jedoch anpassbar:
In [21]: dparser.parse("monkey 10/01/1980 love banana",fuzzy=True, dayfirst=True) Out[21]: datetime.datetime(1980, 1, 10, 0, 0)
quelle
"monkey 10/01/1980 love 7/10/2010 banana"
), wird möglicherweise ein ValueError ausgelöst, oder (wie im Fall von"monkey 10/01/1980 love 2010-07-10 banana"
) wird das zweite Datum möglicherweise falsch interpretiert, indem Stunden, Minuten, Sekunden oder Zeitzonen angegeben werden.fuzzy=True
gibt es Lizenz zu raten.parse
Funktion kann eine Ausnahme auslösen (auch wennfuzzy=True
) oder mitfuzzy=True
, dass sie das erste Datum oder einen Mischmasch zurückgibt, der aus Teilen beider Daten besteht. Also wirklich,parse
sollte nur für eine Zeichenfolge aufgerufen werden, die ein Datum enthält.Zum Extrahieren des Datums aus einer Zeichenfolge in Python; Das beste verfügbare Modul ist das Datefinder- Modul.
Sie können es in Ihrem Python-Projekt verwenden, indem Sie die folgenden einfachen Schritte ausführen.
Schritt 1: Installieren Sie das Datefinder-Paket
Schritt 2: Verwenden Sie es in Ihrem Projekt
import datefinder input_string = "monkey 2010-07-10 love banana" # a generator will be returned by the datefinder module. I'm typecasting it to a list. Please read the note of caution provided at the bottom. matches = list(datefinder.find_dates(input_string)) if len(matches) > 0: # date returned will be a datetime.datetime object. here we are only using the first match. date = matches[0] print date else: print 'No dates found'
Hinweis: Wenn Sie eine große Anzahl von Übereinstimmungen erwarten; Dann wird die Typumwandlung in eine Liste nicht empfohlen, da dies einen hohen Leistungsaufwand bedeutet.
quelle
datefinder
die mehrdeutigepython-dateutil
Datumsübereinstimmung besser war, als nur zwei mögliche Daten aus einem zufälligen Medium.com-Blog-Beitrag zurückzugeben, anstatt fünf. Ichstring = "Assessment Date: 17-May-2017 at 13:31"
list(datefinder.find_dates(string.lower()))
#[]
string = "Assessment Date 17-May-2017 at 13:31"
list(datefinder.find_dates(string.lower()))
#[datetime.datetime(2017, 5, 17, 13, 31)]
Mit Pygrok können Sie abstrahierte Erweiterungen der Syntax für reguläre Ausdrücke definieren.
Die benutzerdefinierten Muster können im Format in Ihre Regex aufgenommen werden
%{PATTERN_NAME}
.Sie können auch eine Beschriftung für dieses Muster erstellen, indem Sie durch einen Doppelpunkt trennen :
%s{PATTERN_NAME:matched_string}
. Wenn das Muster übereinstimmt, wird der Wert als Teil des resultierenden Wörterbuch zurückgeführt wird (zBresult.get('matched_string')
)Zum Beispiel:
from pygrok import Grok input_string = 'monkey 2010-07-10 love banana' date_pattern = '%{YEAR:year}-%{MONTHNUM:month}-%{MONTHDAY:day}' grok = Grok(date_pattern) print(grok.match(input_string))
Der resultierende Wert ist ein Wörterbuch:
{'month': '07', 'day': '10', 'year': '2010'}
Wenn das Datumsmuster nicht in der Eingabezeichenfolge vorhanden ist, lautet der Rückgabewert
None
. Wenn Ihr Muster hingegen keine Beschriftungen enthält, wird ein leeres Wörterbuch zurückgegeben{}
Verweise:
quelle
Sie können auch das Dateparser- Modul ausprobieren , das bei freiem Text möglicherweise langsamer als der Datefinder ist, jedoch mehr potenzielle Fälle und Datumsformate sowie eine erhebliche Anzahl von Sprachen abdecken sollte.
quelle
Wenn Sie die Position des Datumsobjekts in der Zeichenfolge kennen (z. B. in einer Protokolldatei), können Sie das Datum mit .split () [index] extrahieren, ohne das Format vollständig zu kennen.
Zum Beispiel:
>>> string = 'monkey 2010-07-10 love banana' >>> date = string.split()[1] >>> date '2010-07-10'
quelle