在Python中通过冒号分割字符串

4
我有一个提醒应用程序,我需要分割时间,例如3:30 a.m.。我使用了re模块,但失败了。
我的目标是在列表中的单词前使用冒号拆分时间。但是列表中有多个单词,例如a.m.am
程序应该尝试每个单词,直到找到正确的匹配,并通过冒号(如小时和分钟)来拆分时间。13:25变为[13, 25]
以下是示例:
import re

am = ['a.m.', 'am', 'ante meridiem']
timeinp = 'reminder for 3:30 am'

for a in am:
    gettime = re.search(fr'\b\d?\d:\d\d\b {a}', timeinp).group(0)
    gettime = re.split('[:]', gettime)
    print(gettime)

这个代码给我 AttributeError: 'NoneType' object has no attribute 'group'

2个回答

2

如果匹配成功,您可以使用带有捕获组的单个正则表达式即时访问小时和分钟:

import re

am = ['a.m.', 'am', 'ante meridiem']
timeinp = 'reminder for 3:30 am'

a = "|".join(map(re.escape, am))
gettime = re.search(fr'\b(\d{{1,2}}):(\d{{2}})\s*(?:{a})', timeinp)
if gettime:
    print(list(map(int, gettime.groups()))) # => [3, 30]
else:
    print("no match")

请查看Python演示

请注意gettime.groups()包含一个元组,其中包含匹配的所有子组,从1到模式中有多少个组为止。捕获的组是模式中用(...)括起来的所有部分。

您需要使用re.escape转义您的am列表项,否则.会匹配任何字符。您需要在字符类之外使用\.来匹配字面点。


Wiktor,你本可以通过转义括号来修复正则表达式字符串。想知道你为什么决定删除它或使用另一个正则表达式。 - user120242
1
并没有什么“错”的。我是在评论你删除并决定恢复原始正则表达式版本的帖子。\d{1,2}被评估为“(1,2)”,因为有f修饰符。 - user120242
1
@user120242 这没有太大的区别。已经恢复使用 {1,2}{2} - Wiktor Stribiżew
@WiktorStribiżew 如何匹配这个 re,比如 1.5.5 - user14009914
@June self.hour是一个字符串,你为什么要用join连接它?请查看此Python演示以了解如何逐个访问每个组。 - Wiktor Stribiżew
显示剩余4条评论

1
正如其他人所指出的,由于在循环中存储的某个项没有匹配,因此您会收到AttributeError,这是由于re.search()返回None引起的。
下面的示例类似于其他处理re.search()返回None的情况,但它:
  • 使用前瞻来设置模式,以便不包括在返回的匹配项中。
  • 进一步将匹配处理为2个int实例的列表,而不是str实例。
  • print(gettime)后中断循环,以停止任何进一步迭代,并在循环执行后保留分配给gettime的列表值。
  • 包括一些基本逻辑,用于在未按照您的标准匹配时打印No time match found!消息。
import re

am = ['a.m.', 'am', 'ante meridiem']
timeinp = 'reminder for 3:30 am'
gettime = None

for a in am:
     gettime = re.search(fr'\b\d?\d:\d\d\b(?= {a})', timeinp)
     if gettime:
            gettime = [ int(i) for i in re.split(':', gettime.group()) ]
            print(gettime)
            break
            
if not gettime:
    print('No time match found!')

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接