re.sub()没有像我期望的那样工作

时间:2015-05-14 02:07:02

标签: python regex

我在下面给出了一个字符串。

import "image/draw"

...

img.(draw.Image).Set(0, 0, color.RGBA{136, 0, 21, 255})

我想从上面的字符串中提取AppCodename: Mozilla<br>Appversion: 5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/41.0.2272.76 Chrome/41.0.2272.76 Safari/537.36<br> 。我使用以下python程序。

Mozilla

我得到的输出是

import re
import json

with open('data.txt','rb') as f:                                                                                                                                                               
    data = json.load(f)
    message = data['Message']
    appcodename = re.sub('.+AppCodename: ([^<br>])(.*)',r'\1',message,1)
    print('appcode name {}'.format(appcodename))

我的正则表达式有什么问题。

3 个答案:

答案 0 :(得分:2)

您可以考虑比替换更容易匹配:

appcodename = re.search('AppCodename: (\w+)', message).group(1)
print('appcode name {}'.format(appcodename))

eval.in

答案 1 :(得分:1)

使用以下regex

# match anything after AppCodename: and before <br>.
'.*AppCodename: ([\w]+?)<br>(.*)'

输出:

appcode name Mozilla

答案 2 :(得分:1)

正则表达式的问题有两个:

  1. 您使用的是否为[^<br>]的否定课程,其匹配除<br>之外的任何字符(其顺序无关紧要) )。这不会对此特定情况造成任何问题,但建议不要使用否定类来阻止特定字符序列的匹配。

  2. 您希望([^<br>])只匹配1个字符,以匹配多个字符长的Mozilla

  3. 快速&amp;脏修复:

    appcodename = re.sub('.*AppCodename: ([^<br>]+)(.*)',r'\1',message,1)
    

    .*允许匹配,如果字符串以AppCodename开头且([^<br>]+)允许匹配多个字符。

    正如我上面提到的,不建议否定字符类。因此,这是使上述目标更好的下一步:

    appcodename = re.sub(r'.*AppCodename: ((?:(?!<br>).)+).*',r'\1',message,1)
    

    (?:(?!<br>).)+有点慢(这使用负前瞻(?! ... )),但只要<br>不在这些字符中,它就会匹配任意数量的字符。它基本上是检查每个字符,每次都确保在尝试匹配之前该字符没有<br>。接下来,始终建议生成正则表达式字符串以避免意外行为。

    最后,之前和之后的更换不是很实用;匹配会使事情变得更简单:

    appcodename = re.search(r'AppCodename: ((?:(?!<br>).)+)', message).group(1)
    

    此时,你可能会使用类似的东西,它不会使用负面的前瞻,而且更容易阅读,我相信:

    appcodename = re.search(r'AppCodename: (.+?)<br>', message).group(1)