2012-10-19 36 views
0

当我尝试用另一个字符串替换字符串时,它并不总是会发生在re.sub方法中。re.sub in python并不总是替换字符串

sentence = '<date>2004/12/01</date>T09:38:27+01:00'+ 
      'Wed, <date>2012/9/05</date> 10:55:17 UTC %3C%3C%3C' 

time_identifier = u'(?<=[\s\.,T])([\d]{2}[:]{1}[\d]{2}([:]{1}[\d]{2})*[\s\.,+]*(UTC|GMT|CEST|EDT|IST|BST)*(\d\d:\d\d)*)(?=[\s\.,T]|\Z)|'\ 
        u'(?<=\A)([\d]{2}[:]{1}[\d]{2}([:]{1}[\d]{2})*[\s\.,+]*(UTC|GMT|CEST|EDT|IST|BST)*(\d\d:\d\d)*)(?=[\s\.,T]|\Z)' 
time = re.search(time_identifier, sentence, flags=re.U|re.I) 
    if time: 
     try: 
      sentence = re.sub(time.groups()[0], '<time>%s</time>'%time.groups()[0], sentence, flags=re.U|re.I) 
     except: 
      sentence = re.sub(time.groups()[4], '<time>%s</time>'%time.groups()[4], sentence, flags=re.U|re.I) 

对于上面提供的示例,我期望句子的输出是

<date>2004/12/01</date>T<time>09:38:27+01:00<time> 
Wed, <date>2012/9/05</date> <time>10:55:17 UTC</time> %3C%3C%3C 

但应用re.sub方法不替换 “09:38:27 + 01:00”,在原文为

"<time>09:38:27+01:00</time>" 

请问谁能说清楚原因?

+0

如果你打印'time.groups()[0]',你会发现你的正则表达式并没有抓住'09:38:27 + 01:00'。我不知道为什么(而且我不打算通过这个可怕的东西来解决问题并找出答案)。 – mgilson

+0

我没有时间研究你的问题,但我强烈建议http://www.regex101.com/设计你的表情,应该有所帮助。 –

+1

你真的想要简化这个表达式; ''[:] {1}'只是一个非常详细的方式来表示':';例如完全匹配一个冒号。同样,不需要在括号中包括一个'\ d'('[\ d]'与'\ d'相同)。 '\ d \ d'稍短于\ d {2}'。 –

回答

3

你的表情非常复杂。以下是完全相同的模式匹配的简化:

time_identifier = u'(?:(?<=[\s\.,T])|\A)(\d\d:\d\d(:\d\d)*[\s\.,+]*(UTC|GMT|CEST|EDT|IST|BST)*(\d\d:\d\d)*)(?=[\s\.,T]|\Z)' 

你的时间字符串不被因为先行断言(在(?=[\s\.,T]|\Z)部分)的匹配;它限制匹配任何后面跟着空格,句号,逗号,字母T或字符串结尾的任何内容。你的第一个字符串在句子后立即跟着Wed;没有空白。

以下sentence价值确实比赛:

sentence = ('<date>2004/12/01</date>T09:38:27+01:00 ' 
      'Wed, <date>2012/9/05</date> 10:55:17 UTC %3C%3C%3C') 

注意的时区后的额外空间。

1

这里有几个问题。首先,你的复杂模式。其次,你不能这样做:

re.sub('09:38:27+01', "<time>'09:38:27+01'</time>, s) 

因为由于加签串s不匹配模式(我假设你的组包含适当的时间),这样的一部分字符串不会被标记。这回答你的问题。

下面的工作与你的样本数据(虽然也许我过于简单化初始模式):

p = '((?:\\d{2}:\\d{2}:\\d{2}\\+\\d{2}:\\d{2})|(?:\\d{2}:\\d{2}:\\d{2} UTC|GMT|CEST|EDT|IST|BST))' 
result = re.findall(p, s) 
print result 
['09:38:27+01:00', '10:55:17 UTC'] 
r0 = result[0] 
r0 = re.sub('\+', r'\+', r0) 
s = re.sub(r0, "<time>%s</time>" % result[0], s) 
s = re.sub(result[1], "<time>%s</time>" % result[1], s) 
print s 
'<date>2004/12/01</date>T<time>09:38:27+01:00</time>Wed, <date>2012/9/05</date> <time>10:55:17 UTC</time> %3C%3C%3C' 

希望它能帮助。