Регулярное выражение с неполным фрагментом

У меня дан файл с символами. Необохдимо определить максимальную длинну цепочки вида XYZ, при этом сам фрагмент может быть не полным.

Полное описание задачи: Текстовый файл состоит не более чем из 10**6 символов X, Y и Z. Определите максимальную длину цепочки вида XYZXYZXYZ... (составленной из фрагментов XYZ, последний фрагмент может быть неполным).

Пример: XYZXYZXYXX - 8, XYZXYZ - 6 На данный момент имеют вот такой скрипт:

import re

with open('file.txt') as file:
    line = file.readline()

res = re.finditer(r'(XYZ)+', line)
mg = 0
for x in res:
    mg = max(len(x.group()), mg)
print(mg)

Как правильно составить нужное мне выражение? (обычным скриптом я найти смогу, у меня задача именно регулярными выражениями)


Ответы (1 шт):

Автор решения: Wiktor Stribiżew

Регулярные выражения лишь находят совпадения, они не могут найти самую длинную подстроку. Поэтому сначала нужно найти все совпадения, а потом использовать max(), что вы и делаете в своём коде.

Регулярное выражение тут будет

(?:XYZ)+(?:X(?:YZ?))?

См. пример работы регулярного выражения. Подробности:

  • (?:XYZ)+ - одна и более последовательностей XYZ
  • (?:X(?:YZ?))? - опциональная последовательность: X, потом может быть Y, и только если есть уже XY, потом Z.

См. пример кода:

import re

with open('file.txt') as file:
    for line in file:
        matches = re.findall(r'(?:XYZ)+(?:X(?:YZ?))?', line)
        if matches:
            longest = max(matches, key=len)
            print(f'{line}: {longest} (Длина: {len(longest)})')
        else:
            print(f'{line}: NO MATCH')

Результат:

XYZXYZXYXX XYZXYZ: XYZXYZXY (Длина: 8)
XYZXY XYZXYZ: XYZXYZ (Длина: 6)
→ Ссылка