我需要通过一个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'来替换或持续'。'
有没有办法只替换部分比赛?
答案 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 部分用于匹配,但不包括替换。