re.findall возвращает часть найденного текста при поиске повторяющихся фрагментов строки
Допустим, есть строка ABC abcabc fff abcabcabc.
Возможно ли с помощью регулярного выражения получить список вида [ABC, abcabc, abcabcabc]?
Я сделал так:
re.findall(r"(abc)+", str)
Но результат другой :(
Ответы (1 шт):
При использовании метода re.findall с регулярным выражением, содержащим захватывающую подмаску, результатом будет список строк (или список кортежей строк, если таких подмасок больше одной). Так как захватывающая подмаска в данном выражении повторяется (с помощью квантификатора +, но и в любом другом случае, например, {0,10}, *, результат будет похожий), в буфере памяти первой подмаски сохранится только последнее захваченное значение.
Т.е. re.findall(r'(abc)+', 'abcabcabc') вернёт только abc и список длиной в 1 элемент.
Вы можете использовать незахватывающую подмаску, (?:...):
import re
text = 'ABC abcabc fff abcabcabc'
print( re.findall(r'(?:abc)+', text, flags=re.I) )
# => ['ABC', 'abcabc', 'abcabcabc']
См. пример работы программы. Обратите внимание на flags=re.I, флаг регистронезависимого поиска.
В других случаях, если вы не можете заменить захватывающие подмаски на незахватывающие, например, если вы используете обратные ссылки для поиска повторяющихся шаблонов (r'(.)\1{2,}'), тогда вам придётся использовать re.finditer:
[m.group() for m in re.finditer(r'(abc)+', text, flags=re.I)]