我想从类似于此字符串的字符串中提取值:
=== START AAA
one: 11
two: 22
=== START BBB
one: 44
two: 55
three: 66
"三"参数是可选的。我可以逐行解析,但我试图用re.findall做这个。我添加了。*?和(=== | $)这样整个字符串不会被立刻消耗掉。我尝试了很多东西,这似乎是最接近的:
stats_re = re.compile('START (\S+).*?one\s*:\s*(\S+).*?two\s*:\s+(\S+).*?(three\s*:\s+(\S+))?(===|$)',re.DOTALL)
这会产生:
('AAA', '11', '22', '', '', '===')
('BBB', '44', '55', '', '', '')
除了我没有得到"三"参数出现时。
答案 0 :(得分:1)
你的正则表达式很好。你错过了几件事
在大多数情况下,您必须使用一致的.*?
来消费字段。
我评论了需要修改的部分 这是修改后的正则表达式:
START[ ]+(\S+).*?one\s*:\s*(\S+).*?two\s*:\s+(\S+).*?(?:three\s*:\s+(\S+).*?)?(===|$)
扩展:
START [ ]+ # <- Added '+'
( \S+ ) # (1)
.*? one \s* : \s*
( \S+ ) # (2)
.*? two \s* : \s+
( \S+ ) # (3)
.*?
(?: # <- Converted to non-capture
three \s* : \s+
( \S+ ) # (4)
.*? # <- Added '.*?'
)?
( === | $ ) # (5)
输出
** Grp 0 - ( pos 4 , len 33 )
START AAA
one: 11
two: 22
===
** Grp 1 - ( pos 10 , len 3 )
AAA
** Grp 2 - ( pos 20 , len 2 )
11
** Grp 3 - ( pos 30 , len 2 )
22
** Grp 4 - NULL
** Grp 5 - ( pos 34 , len 3 )
===
--------------------
** Grp 0 - ( pos 38 , len 39 )
START BBB
one: 44
two: 55
three: 66
** Grp 1 - ( pos 44 , len 3 )
BBB
** Grp 2 - ( pos 54 , len 2 )
44
** Grp 3 - ( pos 63 , len 2 )
55
** Grp 4 - ( pos 74 , len 2 )
66
** Grp 5 - ( pos 77 , len 0 ) EMPTY