Python regex of date in some text
How can I find as many date patterns as possible from a text file using python? The date pattern is defined as:
dd mmm yyyy
^ ^
| |
+---+--- spaces
Where:
- dd is a two-digit number
- mmm - English three-digit month name (e.g. Jan, Mar, Dec)
- yyyy - four-digit year
- there are two spaces as separators
Thanks!
a source to share
Use the calendar module to give you a little global awareness:
date_expr = r"\d{2} (?:%s) \d{4}" % '|'.join(calendar.month_abbr[1:])
print date_expr
print re.findall(date_expr, source_text)
For me, this creates date_expr as:
"\d{2} (:?Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) \d{4}"
But if I change my language using locale module:
locale.setlocale(0, "fr")
Now I am looking for months in French:
"\d{2} (?:janv.|févr.|mars|avr.|mai|juin|juil.|août|sept.|oct.|nov.|déc.) \d{4}"
Hmm, this is the first time I've ever tried French month abbreviations, I might need to do some cleaning:
date_expr = r"\d{2} (?:%s) \d{4}" % '|'.join(
m.title().rstrip('.') for m in calendar.month_abbr[1:])
Now I am getting:
"\d{2} (?:Janv|Févr|Mars|Avr|Mai|Juin|Juil|Août|Sept|Oct|Nov|Déc) \d{4}"
And now my script will work for my Gaulish friends too, with very little trouble.
(You may be wondering why I had to slice the month_abbr list from [1:] - this list starts with an empty string at position 0, so if you use find () to find the abbreviation of a specific month, you will return a number between 1 and 12 , not from 0-11.)
- Gender
a source to share
Here's a slightly more complete example. The regex will match more than just the correct date value. datetime.strptime
will not be able to analyze everything that is not valid and pick up ValueError
. If the date is parsed, then you have a complete object datetime
that gives you access to a lot of functionality.
>>> from datetime import datetime
>>> import re
>>> dates = []
>>> patn = re.compile(r'\d{2} \w{3} \d{4}')
>>> fh = open('inputfile')
>>> for line in fh:
... for match in patn.findall(line):
... try:
... val = datetime.strptime(match, '%d %b %Y')
... dates.append(val)
... except ValueError:
... pass # ignore, this isn't a date
...
I guess this can be rolled into good hard code with insight if you are so inclined.
a source to share