名为共识的输入文件具有以下形式:
r Tor4ever AAcif1htILdru0BO0qX7OwGVhAU oHlbWBdaN3+QSleqBVL9/yAdcRs 2014-07-31 21:42:43
s Exit Fast Guard HSDir Running V2Dir Valid
v Tor 0.2.4.21
w Bandwidth=231
p reject 25,119,135-139,445,563,1214,4661-4666,6346-6429,6699,6881-6999
r Tornin AA8YrCza5McQugiY3J4h5y4BF9g vNRd1kyQ0i9UsVwYq5YFPHJi3jw 2014-08-01 00:26:18
s Fast Guard HSDir Named Running Stable V2Dir Valid
v Tor 0.2.4.23
w Bandwidth=713
p reject 1-65535
我想解析名称(r行的开头),保护标志(在s行中)和带宽(在w行中),以提供如下内容:
{ {"nickname" : "Tor4ever", "type" : "Guard", "bandwidth" : "231"},
{"nickname" : "Tornin", "type" : "Guard", "bandwidth" : "713"} }
我在制定正确的正则表达式时遇到了麻烦。以下是我正在使用的代码的相关部分:
consensus = file(sys.argv[1]).read()
regex = re.compile('''^r\s(.*?)\s.*?\ns\s.*?(Guard)\s.*?\nw\s.*?([0-9]+)\n''',
re.MULTILINE)
for record in regex.finditer(consensus):
relay = {
'nickname' : record.group(1),
'type' : record.group(2),
'bandwidth' : record.group(3),
}
relays['relays'].append(relay)
open('tor_relays.txt','w').write(json.dumps(relays, indent=4))
有人能告诉我为什么我的正则表达式没有解析我预期的方式吗? 很抱歉很长的帖子,并提前致谢!
答案 0 :(得分:1)
尝试
^r\s(?P<nickname>\b\S+\b).*\n^s\b.*?(?P<type>\bGuard\b).*\n^v.*\n^w\s.*?(?P<bandwidth>\b[0-9]+\b)
它可能比您需要的更冗长,但它使它更容易阅读。 Regex101 demo
import re
p = re.compile(ur'^r\s(?P<nickname>\b\S+\b).*\n^s\b.*?(?P<type>\bGuard\b).*\n^v.*\n^w\s.*?(?P<bandwidth>\b[0-9]+\b)', re.MULTILINE | re.VERBOSE)
test_str = u"r Tor4ever AAcif1htILdru0BO0qX7OwGVhAU oHlbWBdaN3+QSleqBVL9/yAdcRs 2014-07-31 21:42:43 \ns Exit Fast Guard HSDir Running V2Dir Valid \nv Tor 0.2.4.21 \nw Bandwidth=231 \np reject 25,119,135-139,445,563,1214,4661-4666,6346-6429,6699,6881-6999 \nr Tornin AA8YrCza5McQugiY3J4h5y4BF9g vNRd1kyQ0i9UsVwYq5YFPHJi3jw 2014-08-01 00:26:18 \ns Fast Guard HSDir Named Running Stable V2Dir Valid \nv Tor 0.2.4.23 \nw Bandwidth=713 \np reject 1-65535"
re.findall(p, test_str)