Python 用于在 Url 中捕获日期的正则表达式
Python Regex For Capturing Dates in Url
我正在尝试从 URL 的博客等中抓取日期。
由于没有通用的约会方式,我现在依赖
在资源 URL 中的日期。
大部分日期采用以下格式:
url1 = "foo/bar/baz/2014/01/01/more/text"
url2 = "foo/bar/baz/2014/01/more/text"
url3 = "foo/bar/baz/20140101/more/text"
url4 = "foo/bar/baz/2014-01-01/more/text"
url5 = "foo/bar/baz/2014-01more/text"
url6 = "foo/bar/baz/2014_01_01/more/text"
url7 = "foo/bar/baz/2014_01/more/text"
# forgot one
url8 = "foo/bar/baz20140101more/text"
我写了一个暴力代码来得到我想要的。
它很明确,但不够优雅,可能也不是很健壮。
我曾尝试涵盖我匹配“\”或“-”或“_”但没有成功的情况。
所以我很好奇人们是怎么做到的。
虽然我的主要问题是:
在 URL 中捕获日期以将其转换为日期时间对象的最佳稳健方法是什么。
我认为时间元素在格式中并不常见。
干杯!
更新
我相信我从 Casimer 那里得到了解决方案。我想再添加一个
url-我之前错过的日期格式,可能会增加一些麻烦:
# this one maynot have a regex solution. Maybe machine learning.
# and it's not that big a deal if I get the wrong day for this application.
# I think it's safe to assume, that a legit date with Y/M/d with have
# /Y/m/d/ trailing "/"
http://www.nakedcapitalism.com/2014/03/17-million-reasons-rent-control-efficient.html
2014/03/17 # group captured
2014-03-17 00:00:00 # date time object
http://www.nakedcapitalism.com/2014/11/200pm-water-cooler-11514.html
2014/11/20
2014-11-20 00:00:00
# i put more restrictions on the number matching, but perhaps there's a better way...?
pat = r'(20[0-1][0-5]([-_/]?)[0-1][0-9][0-3][0-9])'
现有丑陋的解决方案:
注意:我限制了年份信息,因为我正在捕获不代表日期的数字字符串。另外我觉得那样更稳健。
def get_date_from_url(self, url):
#pat = "(20[0-14]{2}\w+[0-9]{2}(?!\w+[0-9]{2}))"
pat = "(20[0-1][0-5]/[0-9]{2}/[0-9]{2})"
ob1 = re.compile(pat)
pat = "(20[0-1][0-5]-[0-9]{2}-[0-9]{2})"
ob2 = re.compile(pat)
pat = "(20[0-1][0-5]_[0-9]{2}_[0-9]{2})"
ob3 = re.compile(pat)
pat = "(20[0-1][0-5]/[0-9]{2})"
ob4 = re.compile(pat)
pat = "(20[0-1][0-5]-[0-9]{2})"
ob5 = re.compile(pat)
pat = "(20[0-1][0-5]_[0-9]{2})"
ob6 = re.compile(pat)
if ob1.search(url):
grp = ob1.search(url).group()
elif ob2.search(url):
grp = ob2.search(url).group()
elif ob3.search(url):
grp = ob3.search(url).group()
elif ob4.search(url):
grp = ob4.search(url).group()
elif ob5.search(url):
grp = ob5.search(url).group()
elif ob6.search(url):
grp = ob6.search(url).group()
else:
return None
print url
print grp
grp = re.sub('_', '/', grp) # fail to match return orig string
date = to_datetime(grp)
if isinstance(date, datetime.datetime):
print date
else:
return None
你可以使用这个:
pat = r'(20[0-1][0-5]([-_/]?)[0-9]{2}(?:[0-9]{2})?)'
定界符在第 2 组中捕获,因此我对第二个定界符使用反向引用 </code>。分隔符可以是 <code>-
_
或 /
但也是可选的(使用 ?
量词)。
通过将日期放在可选的非捕获组中,这也使日期成为可选的:(?:[0-9]{2})?
请注意,您可以在开头和结尾添加斜杠,以确保路径之间包含日期。
我正在尝试从 URL 的博客等中抓取日期。 由于没有通用的约会方式,我现在依赖 在资源 URL 中的日期。
大部分日期采用以下格式:
url1 = "foo/bar/baz/2014/01/01/more/text"
url2 = "foo/bar/baz/2014/01/more/text"
url3 = "foo/bar/baz/20140101/more/text"
url4 = "foo/bar/baz/2014-01-01/more/text"
url5 = "foo/bar/baz/2014-01more/text"
url6 = "foo/bar/baz/2014_01_01/more/text"
url7 = "foo/bar/baz/2014_01/more/text"
# forgot one
url8 = "foo/bar/baz20140101more/text"
我写了一个暴力代码来得到我想要的。 它很明确,但不够优雅,可能也不是很健壮。
我曾尝试涵盖我匹配“\”或“-”或“_”但没有成功的情况。 所以我很好奇人们是怎么做到的。
虽然我的主要问题是: 在 URL 中捕获日期以将其转换为日期时间对象的最佳稳健方法是什么。
我认为时间元素在格式中并不常见。
干杯!
更新
我相信我从 Casimer 那里得到了解决方案。我想再添加一个 url-我之前错过的日期格式,可能会增加一些麻烦:
# this one maynot have a regex solution. Maybe machine learning.
# and it's not that big a deal if I get the wrong day for this application.
# I think it's safe to assume, that a legit date with Y/M/d with have
# /Y/m/d/ trailing "/"
http://www.nakedcapitalism.com/2014/03/17-million-reasons-rent-control-efficient.html
2014/03/17 # group captured
2014-03-17 00:00:00 # date time object
http://www.nakedcapitalism.com/2014/11/200pm-water-cooler-11514.html
2014/11/20
2014-11-20 00:00:00
# i put more restrictions on the number matching, but perhaps there's a better way...?
pat = r'(20[0-1][0-5]([-_/]?)[0-1][0-9][0-3][0-9])'
现有丑陋的解决方案:
注意:我限制了年份信息,因为我正在捕获不代表日期的数字字符串。另外我觉得那样更稳健。
def get_date_from_url(self, url):
#pat = "(20[0-14]{2}\w+[0-9]{2}(?!\w+[0-9]{2}))"
pat = "(20[0-1][0-5]/[0-9]{2}/[0-9]{2})"
ob1 = re.compile(pat)
pat = "(20[0-1][0-5]-[0-9]{2}-[0-9]{2})"
ob2 = re.compile(pat)
pat = "(20[0-1][0-5]_[0-9]{2}_[0-9]{2})"
ob3 = re.compile(pat)
pat = "(20[0-1][0-5]/[0-9]{2})"
ob4 = re.compile(pat)
pat = "(20[0-1][0-5]-[0-9]{2})"
ob5 = re.compile(pat)
pat = "(20[0-1][0-5]_[0-9]{2})"
ob6 = re.compile(pat)
if ob1.search(url):
grp = ob1.search(url).group()
elif ob2.search(url):
grp = ob2.search(url).group()
elif ob3.search(url):
grp = ob3.search(url).group()
elif ob4.search(url):
grp = ob4.search(url).group()
elif ob5.search(url):
grp = ob5.search(url).group()
elif ob6.search(url):
grp = ob6.search(url).group()
else:
return None
print url
print grp
grp = re.sub('_', '/', grp) # fail to match return orig string
date = to_datetime(grp)
if isinstance(date, datetime.datetime):
print date
else:
return None
你可以使用这个:
pat = r'(20[0-1][0-5]([-_/]?)[0-9]{2}(?:[0-9]{2})?)'
定界符在第 2 组中捕获,因此我对第二个定界符使用反向引用 </code>。分隔符可以是 <code>-
_
或 /
但也是可选的(使用 ?
量词)。
通过将日期放在可选的非捕获组中,这也使日期成为可选的:(?:[0-9]{2})?
请注意,您可以在开头和结尾添加斜杠,以确保路径之间包含日期。