Как заменить только часть матча на python re.sub - PullRequest
49 голосов
/ 04 мая 2010

Мне нужно сопоставить два случая одним выражением reg и выполнить замену

'long.file.name.jpg' -> 'long.file.name_ suff .jpg'

'long.file.name_ a .jpg' -> 'long.file.name_ suff .jpg'

Я пытаюсь сделать следующее

re.sub('(\_a)?\.[^\.]*$' , '_suff.',"long.file.name.jpg")

Но это сокращает расширение '.jpg', и я получаю

long.file.name_suff. вместо long.file.name_suff.jpg Я понимаю, что это из-за [^.] * $ Part, но я не могу исключить это, потому что Я должен найти последнее вхождение '_a' для замены или последнего '.'

Есть ли способ заменить только часть матча?

Ответы [ 4 ]

90 голосов
/ 04 мая 2010

Поместите группу захвата вокруг части, которую вы хотите сохранить, а затем включите ссылку на эту группу захвата в текст замены.

re.sub(r'(\_a)?\.([^\.]*)$' , r'_suff.\2',"long.file.name.jpg")
22 голосов
/ 04 мая 2010
 re.sub(r'(?:_a)?\.([^.]*)$', r'_suff.\1', "long.file.name.jpg")

?: запускает несоответствующую группу ( SO ответ ), поэтому (?:_a) соответствует _a, но не перечисляет его, следующий знак вопроса делает его необязательным.

Таким образом, на английском языке это говорит, соответствует окончанию .<anything>, которое следует (или не следует) шаблону _a

Еще один способ сделать это - использовать lookbehind ( см. Здесь ). Упоминание об этом, потому что они супер полезны, но я не знал о них в течение 15 лет выполнения RE

9 голосов
/ 04 мая 2010

Просто поместите выражение для расширения в группу, запишите его и укажите ссылку в замене:

re.sub(r'(?:_a)?(\.[^\.]*)$' , r'_suff\1',"long.file.name.jpg")

Кроме того, использование группы без захвата (?:…) предотвратит повторное сохранение большого количества ненужной информации.

6 голосов
/ 11 июня 2015

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

re.sub(r'(?<=long.file.name)(\_a)?(?=\.([^\.]*)$)' , r'_suff',"long.file.name.jpg")
>>> 'long.file.name_suff.jpg'

long.file.name и .jpg детали используются при сопоставлениино они исключают из замены.

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