Продолжительность времени до числовых минут с использованием библиотеки Python или регулярных выражений - PullRequest
0 голосов
/ 24 октября 2018

У меня есть строки длительности произвольной формы, содержащие значения часов и минут, одно из которых может быть необязательным

1 hour
12 hours 3 mins
47 mins
10 hours
1 min

Я должен преобразовать их в количество минут.Сначала искал библиотеку Python, которая преобразует время и продолжительность, но строковый формат не позволяет использовать такой подход

Затем я попытался с помощью регулярного выражения извлечь группы чисел:

re.search("(\d+)?.*(\d+\w)", string).group(1)
re.search("(\d+)?.*(\d+\w)", string).group(2)

, который работал длябольшинство случаев, когда присутствуют значения часов и минут или когда присутствует только значение минут (поскольку я сделал первую группу необязательной) Это регулярное выражение завершается ошибкой, когда час состоит из одной цифры (1 час).Кроме того, поскольку я извлекаю только группы цифр без описательного текста (час (ы) и / или мин (с), вычисление неверно, когда есть только значение часа (с двумя цифрами) - например, 10 часов, и оно ошибочно извлекается как2-я группа по минутам.

Ответы [ 4 ]

0 голосов
/ 24 октября 2018

Другие ответы в порядке, еще один способ сделать это с помощью регулярного выражения (если вы действительно хотите):

match = re.match(
    r'((?P<hours>\d+) hours?)? ?((?P<mins>\d+) mins?)?',
    '12 hours 3 mins'
)

match.groupdicts()

Таким образом, может иметь больше смысла для вас (этоосновная проблема в разработке регулярных выражений. Я бы предложил попробовать любое регулярное выражение, выбранное вами, на каком-либо ресурсе, например https://regex101.com/, чтобы провести некоторое тестирование и описание.

0 голосов
/ 24 октября 2018

Я написал этот простой фрагмент, который анализирует все ваши случаи.Спросите, есть ли у вас проблемы.

Вывод:

1 hour -> 1:00:00
12 hours 3 mins -> 12:03:00
47 mins -> 0:47:00
10 hours -> 10:00:00
1 min -> 0:01:00
random text -> 0:00:00

Код:

import re
from datetime import timedelta


number_word_regex = re.compile(r'(\d+) (\w+)')


def parse_fuzzy_duration(s):
    ret = timedelta(0)

    for number, word in number_word_regex.findall(s):
        number = int(number)

        if word in ['minute', 'min', 'minutes', 'mins']:
            ret += timedelta(minutes=number)
        elif word in ['hour', 'hours']:
            ret += timedelta(hours=number)

    return ret


for s in ['1 hour', '12 hours 3 mins', '47 mins', '10 hours', '1 min', 'random text']:
    print(s, '->', parse_fuzzy_duration(s))
0 голосов
/ 24 октября 2018

Вы можете попробовать использовать dateutil и Regex

Демо:

import dateutil.parser as dparser
import re

s = """1 hour
12 hours 3 mins
47 mins
10 hours
1 min"""

for line in s.splitlines():
    print(dparser.parse(re.sub(r"(mins?)", "minutes", line), fuzzy=True).strftime("%H:%M:%S") )

Выход:

01:00:00
12:03:00
00:47:00
10:00:00
00:01:00
0 голосов
/ 24 октября 2018

Вы можете использовать re.findall со следующим регулярным выражением:

import re
s = '''1 hour
12 hours 3 mins
47 mins
10 hours
1 min'''
for h, m in re.findall(r'(?=\d+ *hours?| *\d+ *min(?:ute)?s?)(?:(\d+) *hours?)?(?: *(\d+) *min(?:ute)?s?\b)?', s, flags=re.IGNORECASE):
    print(int(h or 0) * 60 + int(m or 0))

Это выводит:

60
723
47
600
1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...