如何用python re.sub只替换部分匹配


71

我需要通过一个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我理解这是由于[^。] * $部分,但是我不能排除它,因为我必须找到要替换的'_a'或最后的'.a。

有没有办法只替换部分比赛?


您为什么要逃脱下划线(\\_a)?
Amarghosh,2010年

Answers:


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

?:启动一个不匹配的组(SO答案),所以(?:_a)匹配_a而不是枚举它,以下问号使其成为可选。

因此,用英语说,匹配.<anything>模式后面(或不)模式的结尾_a

做到这一点的另一种方法是使用向后看后面)。提及这一点是因为它们非常有用,但我在进行RE的15年中并不了解它们


105

将捕获组放在要保留的零件周围,然后在替换文本中包含对该捕获组的引用。

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

@Amber:我从你的答案中推断出,与str.replace()不同,我们不能在原始字符串中使用变量a);或b)作为re.sub的论点;或 或c)两者。a)合理(我认为),但我不确定b)。不过,似乎我们可以为正则表达式通过的字符串使用变量名。您愿意说明吗?谢谢。
马利克·鲁米

捕获和引用它的部分是什么?
cryanbhu

10

只需将扩展的表达式放在一个组中,捕获它并在替换中引用匹配项:

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

此外,使用非捕获组(?:…)将防止重新存储很多不必要的信息。


7

您可以通过排除要更换的零件来做到这一点。我的意思是,您可以对regex模块说;“与此模式匹配,但替换一部分”。

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

在匹配中使用了long.file.name.jpg零件,但将它们排除在替换范围之外。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.