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

时间:2010-05-04 08:12:29

标签: python regex

我需要通过一个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 个答案:

答案 0 :(得分:88)

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

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

答案 1 :(得分:22)

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

?:启动一个不匹配的群组(SO answer),因此(?:_a)_a匹配但未枚举它,以下问号使其成为可选。

所以在英语中,这表示匹配模式.<anything>

后面(或不是)的结尾_a

另一种方法是使用 lookbehind see here)。提到这一点是因为它们非常有用,但我15年来一直不知道这些REs

答案 2 :(得分:9)

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

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

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

答案 3 :(得分:6)

您可以通过从更换中排除部件来实现。我的意思是,你可以对正则表达式模块说; “匹配这种模式,但替换它的一块”。

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

long.file.name .jpg 部分用于匹配,但不包括替换。