Получение отрезка символов в строке через регулярные выражения
Есть строки, к примеру:
a_god_by_berserk_0bllz.jpg
dream by FutureMan on ArtStation.png
a little old bymer.jpg
deathmatch by trixter.jpg
_ariel_santama__by_recphoto_fullview.jpg (1200×1860).jpg
4_new_photo_by_easypro.png
Нужно из всей этой мешанины вытащить всё то что содержит by(пробел либо земля) строка идущая до нижнего подчёркивания,точки или пробела. Как итог, из приведённого примера нужно вытащить: by_berserk, by FutureMan, by trixter, by_recphoto, by_easypro. Пробовал следующей регуляркой:
by( |_) *(\S|^_|^\.)*
Однако в любом случае, у меня выделяет диапазон либо от by до пробела, либо до конца строки, игнорируя последующие _ и . Последующие мофидирования регулярки вроде:
by( |_) *(?:\S|^_|^\.)*
by( |_) *(\S*|^_*|^\.)
ни к чему не приводят, всё остаётся так же. Так же интересно почему в начале регулярки в месте by( |) *, без пробела до * выделяет только не только by но и слова которые начинаются с by. С пробелом поиск c by и by_. Как пробел решает поведение шаблона - мне не понятно. Ведь по сути я даю шаблон: Ищи с сочетания символов by, затем должно следовать либо пробел, либо подчёркивание, а затем любое количество символов. Помогите с реализацией. Начал изучение регулярок и что-то как то уже не охото.
Ответы (1 шт):
import re
strings = """
a_god_by_berserk_0bllz.jpg
dream by FutureMan on ArtStation.png
a little old bymer.jpg
deathmatch by trixter.jpg
_ariel_santama__by_recphoto_fullview.jpg (1200×1860).jpg
4_new_photo_by_easypro.png
"""
result = re.findall(r"(?:(?<=_)|\b)by[_\s].+?(?=\b|_)", strings)
print(result)
Результат:
['by_berserk', 'by FutureMan', 'by trixter', 'by_recphoto', 'by_easypro']
Расшифровка:
(?:(?<=_)|\b)- Проверка, что слева либо символ подчёркивания, либо граница слова. Причём подчёркивание проверяется методом "просмотра назад"(?<=...)- таким образом он не попадёт в результат. И используются группировки без создания группы(?:...), т.к. они нужны только в выражении, но в результате нам не интересны.[_\s]- Символ подчёркивания или пробельный символ..+?- Любой символ в количестве больше нуля, но по-минимуму.(?=\b|_)- Граница слова или символ подчёркивания. Опять же методом "просмотра вперёд"(?=...), чтобы в результат не попало.
Если сразу нужны только имена (без слова by), то достаточно будет поставить круглые скобки вокруг .+?, т.е. написать так: (.+?)