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})?

请注意,您可以在开头和结尾添加斜杠,以确保路径之间包含日期。