我有一个文本形式的持续时间列表,例如,['142 Days 16 Hours', '128 Days 9 Hours 43 Minutes', '10 Minutes']

我需要构建一个函数来获取这些持续时间,而不是得出总天数.

特定文本可以是一天、天和小时、小时和分钟、一组分钟或一天、小时和分钟.

我try 了以下几种方法:

def parse_dates(data):
    days = int(re.match(r'\d+\sDay', data)[0].split(' ')[0]) if re.match(r'\d+\sDay', data) is not None else 0
    hours = int(re.match(r'\d+\sHour', data)[0].split(' ')[0]) if re.match(r'^\d+Hour*s$', data) is not None else 0
    minutes = int(re.match(r'\d+\sMinute', data)[0].split(' ')[0]) if re.match(r'\d+\sMinute', data) is not None else 0

    days += hours / 24
    days += minutes / 1440

    return days

无论使用re.match()还是re.search(),提供的函数都会失败,这让我相信表达式本身存在问题.

但是,小时和分钟始终显示为0.我如何修复我的regex,或设计出更好的解决方案,以适当地解析这些文件?

推荐答案

您可以try 以下正则表达式(Demo):

(?:(\d+) Days?)?(?: ?(\d+) Hours?)?(?: ?(\d+) Minutes?)?

Explanation:

  • (?:...)标记为非捕获组
  • (...)表示被捕获的组
  • 符号或组后的?表示它是可选的
  • \d+表示一个或多个数字(0123...)

样例Python实现:

import re

_DHM_RE = re.compile(r'(?:(\d+) Days?)?(?: ?(\d+) Hours?)?(?: ?(\d+) Minutes?)?')
_HOURS_IN_DAY = 24
_MINUTES_IN_DAY = 60 * _HOURS_IN_DAY


def parse_dates(s: str) -> int:
    m = _DHM_RE.search(s)
    if m is None:
        return 0

    days = int(m.group(1) or 0)
    hours = int(m.group(2) or 0)
    minutes = int(m.group(3) or 0)

    days += hours / _HOURS_IN_DAY
    days += minutes / _MINUTES_IN_DAY

    return int(days)


strings = """\
142 Days 16 Hours
128 Days 9 Hours 43 Minutes
10 Minutes
52 Hours
""".splitlines()

for s in strings:
    d = parse_dates(s)
    print(f'{s!r} has {d} days.')

Python相关问答推荐

使用索引列表列表对列进行切片并获取行方向的向量长度

删除字符串中第一次出现单词后的所有内容

OR—Tools中CP—SAT求解器的IntVar设置值

如何从数据库上传数据到html?

海上重叠直方图

如何使Matplotlib标题以图形为中心,而图例框则以图形为中心

Python中的变量每次增加超过1

旋转多边形而不改变内部空间关系

在不同的帧B中判断帧A中的子字符串,每个帧的大小不同

在输入行运行时停止代码

如何在两列上groupBy,并使用pyspark计算每个分组列的平均总价值

numpy数组和数组标量之间的不同行为

Python—在嵌套列表中添加相同索引的元素,然后计算平均值

应用指定的规则构建数组

Pandas:将值从一列移动到适当的列

正在try 让Python读取特定的CSV文件

Python:在cmd中添加参数时的语法

了解如何让库认识到我具有所需的依赖项

将时间序列附加到数据帧

基于2级列表的Pandas 切片3级多索引