Как заменить только часть соответствия на python re.sub
Мне нужно совместить два случая одним выражением 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" для замены или последнего ".
Есть ли способ заменить только часть матча?
Ответы
Ответ 1
re.sub(r'(?:_a)?\.([^.]*)$', r'_suff.\1', "long.file.name.jpg")
?:
запускает несоответствующую группу (SO ответ), поэтому (?:_a)
соответствует _a
, но не перечисляет его, следующий знак вопроса делает это необязательно.
Итак, по-английски, это говорит, что соответствие заканчивается .<anything>
, которое следует (или не соответствует) шаблону _a
Другой способ сделать это - использовать lookbehind (см. здесь). Упомя все это, потому что они супер полезны, но я не знал о них в течение 15 лет с REs
Ответ 2
Поместите группу захвата вокруг части, которую вы хотите сохранить, а затем включите ссылку на эту группу захвата в текст замены.
re.sub(r'(\_a)?\.([^\.]*)$' , r'_suff.\2',"long.file.name.jpg")
Ответ 3
Просто поместите выражение для расширения в группу, запишите его и укажите совпадение в замене:
re.sub(r'(?:_a)?(\.[^\.]*)$' , r'_suff\1',"long.file.name.jpg")
Кроме того, использование группы, не содержащей захвата (?:…)
, не позволит повторно хранить много ненужной информации.
Ответ 4
Вы можете сделать это, исключив детали из замены. Я имею в виду, вы можете сказать модулю регулярного выражения; "совпадение с этим шаблоном, но замените его частью".
re.sub(r'(?<=long.file.name)(\_a)?(?=\.([^\.]*)$)' , r'_suff',"long.file.name.jpg")
>>> 'long.file.name_suff.jpg'
long.file.name и .jpg части используются для сопоставления, но они исключаются из замены.
Ответ 5
Что если я хочу сделать замену для типа '\ 1 $ {variable}\3'? как мне это сделать?