2010-05-04 124 views
34

我需要一个reg表达式两种情况相匹配,并进行替换如何使用Python应用re.sub替换匹配的唯一部分

“long.file.name.jpg” - >“long.file.name_ SUFF .JPG”

'long.file.name_ 一个 .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

你为什么要逃避下划线'(\\ _ a)?' – Amarghosh 2010-05-04 08:17:58

回答

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

?:开始非匹配组(SO answer),所以(?:_a)是匹配的_a但不是列举它,下面的问号使得可选的。

因此,在英语,这是说,匹配结束.<anything>后面(或没有)的模式_a

另一种方式做,这将是使用回顾后see here)。提到这一点是因为它们超级有用,但我不知道它们在做RE的15年中的效果。

+26

此答案缺少解释。 – PLPeeters 2016-05-30 13:25:52

+0

你能解释一下吗? – 2016-12-01 14:32:01

72

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

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

感谢您对正在做什么的解释。 – GreenMatt 2012-12-07 22:24:57

+0

@Amber:我从你的回答推断,与str.replace()不同,我们不能在原始字符串中使用变量a);或者b)作为re.sub的参数。或者c)两者。 a)有意义(我认为),但我不确定b)。不过,我们似乎可以使用正则表达式正在经历的字符串的变量名称。你愿意澄清吗?谢谢。 – 2017-06-09 01:39:09

7

只需将表达为扩展成团,捕捉它和在更换引用匹配:

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

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

+3

您需要在'\ 1'中将反斜杠转义或者将其放入'r'''而不是''''中。 – Amber 2010-05-04 08:17:59

1

您可以通过排除替换零件来实现。我的意思是,你可以对正则表达式模块说; “与这种模式相匹配,但取而代之”。

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

long.file.name的.jpg部件上正在匹配中使用,但它们是从更换排除。