You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Python正则表达式将字符串中的datetime.datetime对象替换为数字列表

如何用Python正则表达式将字符串中的datetime.datetime对象替换为数字列表

我懂你遇到的问题,就是想把字符串里那些datetime.datetime(...)格式的内容,替换成里面的数字组成的列表对吧?咱们先看看你原来的正则哪里出问题了。

你的原正则是:

DATETIME_PATTERN = r"datetime.datetime\(((\d+)(,\s*\d+)*), tzinfo=.*\)"

这里的.*是贪婪匹配,会把从tzinfo=开始后面的所有内容都“吞”掉,直到字符串末尾,这就导致它会误替换掉中间不该动的内容,比如后面的'bar': 'some data'部分也被卷进去了,这肯定不是你想要的。

那怎么改呢?关键是要让正则只匹配当前datetime.datetime(...)内部的tzinfo部分,而不超出这个对象的范围。

改进后的正则方案

我们可以把贪婪的.*换成更精确的匹配,比如只匹配到右括号)之前的内容,这样就能精准锁定单个datetime对象的范围:

import re

input_str = "{'foo': datetime.datetime(2022, 5, 23, 0, 0, tzinfo=tzlocal()), 'bar': 'some data', 'foobar': datetime.datetime(2022, 8, 3, 13, 57, 41, tzinfo=<UTC>), 'barlist': ['hello', 'world']}"

# 改进的正则:精准匹配单个datetime.datetime对象,捕获数字部分
DATETIME_PATTERN = r"datetime\.datetime\((\d+(?:,\s*\d+)*), tzinfo=[^)]*\)"
modified_input_str = re.sub(DATETIME_PATTERN, r"[\1]", input_str)

print(modified_input_str)

这里的关键改动点:

  • datetime\.datetime:转义了点号,因为正则里.默认匹配任意字符,必须转义才能匹配字面意义的点
  • (\d+(?:,\s*\d+)*):捕获所有数字和分隔的逗号+空格组合,(?:...)是非捕获组,只用来重复匹配逗号加数字的模式,不会额外生成捕获组
  • tzinfo=[^)]*:[^)]表示匹配除了右括号)之外的任意字符,这样就不会超出当前datetime对象的括号范围,完美避免了贪婪匹配的问题

运行这段代码后,就能得到你想要的结果:

{'foo': [2022, 5, 23, 0, 0], 'bar': 'some data', 'foobar': [2022, 8, 3, 13, 57, 41], 'barlist': ['hello', 'world']}

你自定义调整的版本

你后来也针对自己的特定需求修改了正则:

DATETIME_PATTERN = r"datetime\.datetime\((\d+(?:,\s*\d+)*), tzinfo=(?:[^\s\d])*\)"

这个版本把[^)]*换成了(?:[^\s\d])*,也就是只匹配非空白、非数字的字符,因为你知道自己场景里tzinfo=后面的内容不会有空格或数字,这个限制更严格,能进一步降低误匹配的概率,非常贴合你的实际需求。

这样调整后,正则的匹配精度就完全符合你的要求,不会再出现替换大段无关内容的问题了。

备注:内容来源于stack exchange,提问作者avhhh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.23 15:29:07