我在下面给出了一个字符串。
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))
我的正则表达式有什么问题。
答案 0 :(得分:2)
您可以考虑比替换更容易匹配:
appcodename = re.search('AppCodename: (\w+)', message).group(1)
print('appcode name {}'.format(appcodename))
答案 1 :(得分:1)
使用以下regex
:
# match anything after AppCodename: and before <br>.
'.*AppCodename: ([\w]+?)<br>(.*)'
输出:
appcode name Mozilla
答案 2 :(得分:1)
正则表达式的问题有两个:
您使用的是否为[^<br>]
的否定课程,其匹配除<
,b
,r
和>
之外的任何字符(其顺序无关紧要) )。这不会对此特定情况造成任何问题,但建议不要使用否定类来阻止特定字符序列的匹配。
您希望([^<br>])
只匹配1个字符,以匹配多个字符长的Mozilla
。
快速&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)