python - re.sub 的 repl 表达式中不能调用 capture-group 上的函数?例如 int(r'\1')
问题描述
(这个问题的目的是找到一个优雅的 Python 习语来解决无法将捕获组引用传播到函数调用中的repl 表达式,re.sub()
r'\1'
int()
例如。不要挂断特定parse_ampm
示例,显然是 am-pm解析可以通过 stdlib 调用来完成,这不是重点)。
考虑在时间字符串中解析可选的“PM”'hPM'
或'hhPM'
(可选的分钟或秒,'h:mmPM'
或'h:mm:ssPM'
)示例:'11', '11PM', '4:10', '4:10PM', '12:11:10PM'
.
...并通过将小时转换为整数来替换它,添加 12,然后转换/格式化回字符串,并附加(可选)MM:SS。显然,这可以在 Python 中以各种粗鲁的方式完成,但显然不是简单的单行re.sub
,因为repl
-expression 只能处理直接的捕获组引用,例如r'\1'
,而不能将它们传递给类似的函数int()
:
BAD 1)re.sub()
不会传播r'\1'
到表达式中的函数调用int()
中repl
:
>>> re.sub(r'(\d+)(:\d+)?(PM)', lambda m: int(r'\1') + 12, '4:10PM')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: '\\1'
BAD 2)我们也不能re.sub
在 f-string 中使用反向引用(Python 3.7),第二个原因:因为实际的 f-string 本身是在解释时构建的,而不是在运行时构建的:
>>> re.sub(r'(\d+)(:\d+)?(PM)', fr'{int(\1) + 12}\2', s2)
File "<stdin>", line 1
SyntaxError: f-string expression part cannot include a backslash
解决方案3)笨重的分段方法:
def parse_ampm(x):
"""Parse 'HH(:MM:SS)(AM/PM)' time-string, strip AM/PM, correct hour+12 for PM"""
hmsn = list( re.match('(\d+)([:\d]*)?(?P<nm>AM|PM)?', x).groups() )
hmsn[0] = int(hmsn[0])
if (hmsn[-1] == 'PM') ^ (hmsn[0] == 12):
hmsn[0] = (hmsn[0] + 12) % 24
return f'{hmsn[0]}{hmsn[1]}'
for s in ['4', '4:10', '4:10PM', '12:11:10PM']:
parse_ampm(s)
解决方案 3b)另一种笨重的分段方法:
if s.endswith('PM'):
hms = s2[:-2].split(':') # optional MM:SS
hms[0] = int(hms[0])+12
s = ':'.join(str(x) for x in hms)
解决方案 4)基于 dict 的 hacky 方法将所有 12 个可能的小时值映射到str(int(hour)+12)
不需要整数运算,这看起来很丑陋和 hacky(但我想最快):
adjust_for_pm = {str(h):str(h+12) for h in range(1,12+1)}
adjust_for_pm.get(h)
笔记:
- 我想看看对于一般用例来说最简单的基本 Python 习语是什么,我想你必须避免
re.sub()
并手动处理 a 的组re.match(...).groups()
。是的,我知道datetime.strptime()
,dateutil.parser.parse()
和其他 stdlib 函数处理我拥有的这个特定示例,或者这个解决方案适用于非常狭窄的用例,但没有解决一般问题“如何解决 repr 表达式中的 '\1'?” ,但这里的时间字符串不附带日期,我不想附加令牌日期然后将其删除。 - 如果可以的话,可以加分a)静默抑制可选的'AM',b)在小时内保留可选的前导字符串'0' c)参数化小时:分钟:秒分隔符':'
- 这个问题来自Manipulate time-range in a pandas Dataframe
解决方案
推荐阅读
- r - 在 R 中,如何找到列中包含任何值的行
- android - 检查来自json的条件
- python-3.x - 如何使用 pandas 获取数据库中单词的计数
- javascript - 如何渲染一个以 TR 为根元素的 vue 组件?
- vb.net - “克隆”带有颜色的 Excel 文件单元格 (xlsx)
- excel - Excel 不接受 SelfCert 数字证书
- python - 如何使用Python访问boto存储桶中文件夹中的文件?
- javascript - 在 JS 函数中包含变量字符串(HTA 应用程序)
- python - 使用keyboard.is_pressed时如何抑制键?
- ios - 设置通用链接