Как сделать не жадное регулярное выражение на голове - PullRequest
1 голос
/ 18 марта 2020

Вот строка, например:

Clone into repo1...
some text
Clone into repo2...
some text
Clone into repo3...
some text
fatal: Some exception was thrown.

Я пытаюсь получить последний "Клон в repo3" и фатальное сообщение. Вот регулярное выражение, которое я пишу: (Clone into.+fatal:.+?$) с флагами, re.DOTALL и `re.MULTILINE

Но я получил все сообщение. Я знаю, что каким-то образом мы можем сделать это .*(Clone into.+fatal:.+?$), но текст, который я имею в виду, действительно большой, если использовать .* спереди, это приведет к огромным затратам времени.

Спасибо всем за вашу помощь!

РЕДАКТИРОВАТЬ

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

Вот структура, которую я написал:

# Here's almost 10 compiled regex, some of them have this duplicated issue.
regex_list = [...]

for regex in regex_list:
    res = regex.findall(log_text)
    if res:
        reason = res[0]
        break

Если нет способа справиться с этой проблемой с помощью регулярных выражений, возможно, я пересмотрю вопрос об изменении всех этих регулярных выражений в общую функцию, чтобы сначала выполнять rsplit.

Кстати, способ rsplit требует остановки теста после выдачи фатальной ошибки. Если тест продолжает выполняться после возникновения фатальной ошибки, этот метод не будет соответствовать исключению ...

1 Ответ

2 голосов
/ 18 марта 2020

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

import re

text = """
    Clone into repo1...
    some text
    Clone into repo2...
    some text
    Clone into repo3...
    some text
    fatal: Some exception was thrown.
    """

# Get the part after the last 'Clone into '
end = text.rsplit("Clone into ", 1)[1]
# Capture clone and fatal messages.
match = re.search(r'\A(.*)\r?\n[\s\S]*?\b(fatal: .*)', end)
# Fetch captures, if there are any.
groups = None if match is None else match.groups()

print(groups)

Вывод:

('repo3...', 'fatal: Some exception was thrown.')

Если вам все еще нужна фраза Clone into, просто добавьте ее перед тем, как использовать первую группу захвата. Все это может быть сделано более элегантно с подстрокой, но синтаксис ускользает от меня.

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