2011-03-16 60 views
10

python新增功能。这可能很简单,但我还没有找到答案。如何在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的其实并不重要的价值。假设它的随机或从用户输入(我把静态vals在这里保持简单)。谢谢你的帮助。

回答

21

您的反向引用不明确。你替换字符串变成

\120101215\220101216 

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

为了解决这个问题,使用此语法:

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

也有太多的套括号(或“括号”,如果你像我一样说英式英语:) - 你不需要括号围绕[0-9]{8}部分,你不是反向参考:

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

应该足够。 (并且,如其他地方所述,不要使用str作为变量名称,除非您想花费年龄调试为什么str.replace()不再有效,不是我曾经这么做过一次......没有。:)

所以整个事情变成:

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
rndStr = "20101215" 
rndStr2 = "20101216" 
mys = "Looking at dates between {0} and {1}".format(rndStr, rndStr2) 

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

+1

我不认为OP要求这样做。 – 2011-03-16 22:13:15

+0

原始字符串有两个(不同)日期,所以这不会工作。不管怎么说,还是要谢谢你。 – 2011-03-17 14:42:58

3

注意,如果你改变的rndStr或01的值到文本(比如'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的docs:

(?P<name>...)

定期括号相似,但 由组相匹配的字符串是通过符号 的 正则表达式的其余部分中访问组名“name”。组名必须为 有效的Python标识符,并且每个 组名必须在正则表达式中仅定义一次 。 A 符号组也是一个编号为 的组,就好像该组不是 命名。因此,在下面的例子 名为'id'的组也可被引用作为 编号组1

例如,如果图案是 (?P<id>[a-zA-Z_]\w*),该基团可以是 通过其名称在参数参照的 方法匹配的对象,如 m.group('id')m.end('id'),并且还通过 名称在给予.sub()正则表达式 本身(使用(?P=id))和替换 文本(使用\g<id>)。

+0

谢谢 - 希望我可以分配两个正确的答案:-) – 2011-03-17 14:40:50

+0

@Syed H:所有的事情都是平等的,你应该选择第一个正确的答案恕我直言,这就是你所做的。我添加了我的答案,只是作为替代...感谢您的评论。 – dawg 2011-03-17 15:41:35

-1
rndStr = "20101215" 
rndStr2 = "20101216" 

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

同样在这里,原始字符串有两个(不同的)日期,所以这不会工作。不管怎么说,还是要谢谢你。 – 2011-03-17 14:43:38

相关问题