如何在Python中使用匹配的组和变量进行子化

时间:2011-03-16 21:26:01

标签: python regex

python新手。这可能很简单,但我没有找到答案。

rndStr = "20101215"
rndStr2 = "20101216"
str = "Looking at dates between 20110316 and 20110317"
outstr = re.sub("(.+)([0-9]{8})(.+)([0-9]{8})",r'\1'+rndStr+r'\2'+rndStr2,str)

我正在寻找的输出是:

Looking at dates between 20101215 and 20101216

但我得到了:

P101215101216

两个rndStr的值并不重要。假设它是随机的或取自用户输入(我在这里放置静态val以保持简单)。谢谢你的帮助。

4 个答案:

答案 0 :(得分:24)

你的反对意见含糊不清。您的替换字符串变为

\120101215\220101216

这是两个相当大的数字反向引用:)

要解决此问题,请使用以下语法:

r'\g<1>'+rndStr+r'\g<2>'+rndStr2 

你也有太多的括号(如果你像我这样说英国英语,还是“括号”) - 你不需要围绕你没有反向引用的[0-9]{8}部分的括号:

re.sub("(.+)[0-9]{8}(.+)[0-9]{8}",...

应该足够了。

(并且,正如其他地方所述,不要使用str作为变量名。除非你想花费多年时间调试为什么str.replace()不再起作用。不是说我曾经这样做过...... noooo。:)

所以整个事情变成:

import re
rndStr = "20101215"
rndStr2 = "20101216"
s = "Looking at dates between 20110316 and 20110317"
outstr = re.sub("(.+)[0-9]{8}(.+)[0-9]{8}", r'\g<1>'+rndStr+r'\g<2>'+rndStr2, s) 
print outstr

产:

Looking at dates between 20101215 and 20101216

答案 1 :(得分:3)

请注意,如果您将rndStrrndStr2的值更改为文本(例如“abc”)而不是数字,那么您会得到更接近预期结果的内容吗?

re.sub的表达式中,您有r'\1'+rndStr+...这会合并到'\1'+'20101215',然后尝试引用\120101215的后引用,这可能不是您想要的。

您可以使用命名的后引用使后引用明确:

rep1 = "20101215"
rep2 = "20101216"
st = "Looking at dates between 20110316 and 20110317"

print re.sub(r'(?P<fp>.+)[0-9]{8}(?P<lp>.+)[0-9]{8}',
            r'\g<fp>'+rep1+r'\g<lp>'+rep2,st)

更好的是,使用更容易理解的语法并检查尝试匹配的返回:

m=re.search(r'(?P<fp>.+)[0-9]{8}(?P<lp>.+)[0-9]{8}',st)
if m:
    print m.group('fp')+rep1+m.group('lp')+rep2  #you could use m.group(1) too
else:
    print "no match..."

在任何一种情况下,都会生成所需的Looking at dates between 20101215 and 20101216 字符串。

关于命名反向引用的Python文档:

(?P<name>...)

  

与常规括号相似,但是   该组匹配的子串是   其余的可以访问   通过象征性的正则表达式   组名'名称'。组名必须是   有效的Python标识符,以及每个   组名必须只定义一次   在正则表达式中。一个   象征性群体也是一个编号   小组,就好像小组没有   命名。所以这个组名为'id'   以下示例也可以参考   作为编号组1。

     

例如,如果模式是   (?P<id>[a-zA-Z_]\w*),小组可以   在其参数中引用其名称   匹配对象的方法,例如   m.group('id')m.end('id'),以及   在正则表达式中按名称   本身(使用(?P=id))和替换   提供给.sub()的文字(使用\g<id>)。

答案 2 :(得分:-1)

rndStr = "20101215"
rndStr2 = "20101216"
mys = "Looking at dates between {0} and {1}".format(rndStr, rndStr2)

请不要将str用作变量名称;它会覆盖内置的str类型。

答案 3 :(得分:-1)

rndStr = "20101215"
rndStr2 = "20101216"

print "Looking at dates between %s and %s" %(rndStr,rndStr2)