有趣的正则表达式小问题

Keywords: #技术 #Python #正则表达式

今天在使用 Python 编写爬虫程序的过程中,遇到了一个 BUG,最终发现居然是关于一个正则表达式中的小问题,十分有趣。

我编写了这样一个爬虫程序,爬取网页中发布文章的标题和发布时间,于是我写了这样一个正则表达式来匹配文章发布的时间。

date_match = re.match(r'(\d{4})年(\d{2})月(\d{2})日', date)

这样咋一看似乎非常正确,我一开始也没有意识到错误。直到程序开始运行了一段时间,我打开日志文件,发现从 10 月 10 日之后的文章都不能正确读取,而到了 23 年的 12 月又开始正常读取了。

我当时觉得这样的 BUG 十分奇怪,为什么不能读取的文章时间怎么有规律。同时,由于项目代码量不小,我几乎在可能出错的地方都进行了异常的抛出,但是在日志文件中却没有出现任何的错误,这让我百思不得其解。

于是我只能在我认为可能出现问题的地方手动 print 打印传递的变量信息,逐渐缩小范围,“真凶”也随着浮出水面。问题就出在我上面写的那句正则表达式匹配时间的代码。

事实上,页面上的时间并不是固定 2 位数,当出现个位数日期时,它只显示 1 位数字,比如 2024年10月1日,而非 2024年10月01日。所以,我一开始写的代码只能匹配 2 位数字,我也确实忘记考虑个位数字的情况,这就导致 re.match 会返回一个 None,再加上我后面直接使用 if data_match: 把这种情况排除在外,而不是抛出一个异常,我也因此排查了很久。

这样的话,10 月 10 日之后的日期都不能读取的现象就很好理解了,因为后面就都是个位数的天数和月份了,比如 10 月 9 日或者 9 月 10 日。只有到 2023 年 12 月份开始才能正常匹配了。

解决的办法也很简单,改成匹配 1 位或 2 位数字就可以了。

date_match = re.match(r'(\d{4})年(\d{1,2})月(\d{1,2})日', date)

1