Несколько шаблонов регулярных выражений для получения значений из элементов списка

У меня есть список ниже. Мне нужно извлечь значения времени и суммировать их в целом из приведенного ниже списка.

Значения времени могут располагаться в разных местах – например. квадратные скобки, круглая скобка, в конце строки, в начале и т.д.

Я надеялся использовать одно регулярное выражение с несколькими возможностями OR (|), чтобы пройти через каждую строку в списке и извлечь значения, чтобы иметь возможность сложить их вместе.

summary = [
    "CHGnnnnnnnnn (2.5)",
    "CHGnnnnnnnnn - 0.5",
    "2 hours - CHGnnnnnnnnn - some random words",
    "1.25 hours - CHGnnnnnnnnn - more random words",
    "CHGnnnnnnnnn [2],",
    "CHGnnnnnnnnn - yet more words - 2 hrs",
    "CHGnnnnnnnnn, CHGnnnnnnnnn - 4hrs",
    "CHGnnnnnnnnn another word-     2.5",
    "1 hour - CHGnnnnnnnnn -",
    "CHGnnnnnnnnn - 00552988-  3",
    "CHGnnnnnnnnn(30m)",
    "CHGnnnnnnnnn - more words that is not needed - 4.75"
]

Это код, который у меня есть на данный момент, который подходит только для сценариев, в которых время указывается в квадратных скобках или круглых скобках. Как только я пытаюсь свой мозг регулярных выражений включить другие строки, где время не заключено в скобки, он ломается.

import re

summary = [
    "CHG453689356 (2.5)",
    "CHG190394857(2.5) , CHG000159040 (3)",
    "CHG098764573 [2],"
]

# Define regex pattern to extract hours
time_pattern = re.compile(r'\((\d+(\.\d*)?)\)|\[(\d+(\.\d*)?)\]')

# Initialize total hours accumulator
total_hours_all_lines = 0

# Extract and sum hours for each line
for entry in summary:
    # Initialize total hours accumulator for the current line
    total_hours_line = 0
    
    # Find all matches of time pattern in the entry
    time_matches = time_pattern.findall(entry)
    
    # Iterate over matches and sum the hours for the current line
    for match in time_matches:
        # Check if group 0 has a valid number (for parentheses)
        if match[0]:
            total_hours_line += float(match[0])
        # Check if group 2 has a valid number (for square brackets)
        elif match[2]:
            total_hours_line += float(match[2])

    # Print the total hours for the current line
    print(f"Total hours for line '{entry}': {total_hours_line}")
    
    # Add the current line's total hours to the total for all lines
    total_hours_all_lines += total_hours_line

# Print the total hours for all lines
print(f"Total hours for all lines: {total_hours_all_lines}")

Какие выходы:

Total hours for line 'CHG453689356 (2.5)': 2.5
Total hours for line 'CHG190394857(2.5) , CHG000159040 (3)': 5.5
Total hours for line 'CHG098764573 [2],': 2.0
Total hours for all lines: 10.0

Вы вообще что-нибудь пробовали? Такой сайт, как regex101.com, может стать отличным подспорьем для экспериментов — не стесняйтесь спрашивать здесь, считаете ли вы, что у вас есть что-то, что должно работать, но не работает каким-то конкретным образом. Просто отредактируйте свой вопрос и поделитесь своими попытками с описанием конкретной проблемы, с которой вы столкнулись. Кроме того, похоже, что вы предоставили некоторые образцы данных, но ваши фактические данные могут содержать символы, которые могут нарушить решение, которое будет работать в этом образце. Убедитесь, что то, чем вы делитесь, соответствует реальным данным (например, есть ли цифры в остальной части текста?)

Grismar 15.06.2024 06:25

Числовые значения времени имеют разные единицы измерения; а некоторые числа вообще не имеют единиц измерения.

Tim Biegeleisen 15.06.2024 06:59

Да, к сожалению, все значения времени представляют собой свободный текст, введенный людьми.

Ruan 15.06.2024 09:08
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
3
65
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Мое предложение состояло бы в том, чтобы игнорировать проблему заключения в скобки - в любом случае не все ваши примеры содержат парные скобки любого типа - и вместо этого сосредоточиться на числах в приемлемом диапазоне.

    time_matches = re.seach(r"\b\d{1,2}(?:\.\d{1,2})?(?:h(?:rs?)?|m(?:in)?)?\b", entry)

Это переключается с findall на просто search; ни один из ваших примеров не содержит более одного выражения времени.

Это все еще довольно эвристично. Если вы хотите немного ужесточить его, вы можете указать, что часы должны быть однозначными (или, по крайней мере, меньше, скажем, шестнадцати?), а минуты должны быть двузначными. Затем вы также можете разрешить часы, за которыми следуют минуты, вместо того, чтобы требовать только одно число. Но ни один из ваших примеров этого не требует, поэтому я туда не пошел.

Демо: https://regex101.com/r/yUUhGH/1

Без требования единиц измерения или строгих соглашений о форматировании невозможно справиться с такими гипотетическими записями, как

работа над проектом 2 (3)

указать 3 часа работы.

Именно из-за подобных проблем бюрократам нравятся формы, в которых вы можете предоставить только необходимую информацию в строго определенном формате. Тогда легко обрабатывать, но невозможно обрабатывать случаи, которые каким-то образом требуют специальной обработки, ручной проверки или взаимодействия.

В конце концов, если вам требуется высокая точность без проверки человеком, лучшим решением может быть система, которая требует, чтобы отправители разбивали записи на «что» и «на какой срок», где для последнего разрешен ввод только чч:мм; или, возможно, какая-то система НЛП, позволяющая попытаться понять смысл текста на основе лингвистического анализа (но даже в этом случае я не понимаю, как это может быть надежным).

Спасибо, тройное, очень ценю обратную связь. Согласен на 100%, лучшим решением было бы настроить систему захвата на точную продолжительность в универсальном формате.

Ruan 16.06.2024 00:25

Другие вопросы по теме