在 Python 中用冒号分割字符串

Splitting string by colon in Python

我有一个提醒应用,我需要像 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'

您可以将单个正则表达式与捕获组一起使用,以便在匹配时立即访问小时和分钟:

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 demo

请注意 gettime.groups() 包含一个 包含匹配的所有子组的元组,从 1 到模式中有多少组。 捕获组都是用 (...).

括起来的那些模式部分

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

正如其他人所指出的,如果存储在 am 中的项目在其中不匹配,则由于 re.search() 返回 None,您将得到 AttributeError你的循环。

下面的例子在处理 re.search() returns None 的情况下与其他例子类似,但是它:

  • 在模式中使用前瞻性以不在返回的匹配项中包含 am 项。
  • 进一步将匹配处理成 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!')