Kim*_*ais 8 python regex parsing python-2.6
我有一个天真的"解析器",只是做了类似的事情:
[x.split('=') for x in mystring.split(',')]
但是mystring可以是类似的东西
'foo=bar,breakfast=spam,eggs'
显然,
天真的分裂者不会这样做.我仅限于Python 2.6标准库,
因此例如pyparsing不能使用.
预期的产出是
[('foo', 'bar'), ('breakfast', 'spam,eggs')]
我正在尝试使用正则表达式,但面临以下问题:
我的第一次尝试
r'([a-z_]+)=(.+),?'
给了我
[('foo', 'bar,breakfast=spam,eggs')]
显然,
使.+非贪婪不解决问题.
所以,
我猜我必须以某种方式使最后一个逗号(或$)成为强制性的.
这样做并没有真正起作用,
r'([a-z_]+)=(.+?)(?:,|$)'
因为包含一个值的逗号后面的东西被省略了,
例如[('foo', 'bar'), ('breakfast', 'spam')]
我想我必须使用某种后视(?)操作.
问题
1. 我使用哪一个?或
2. 我该怎么做/这个?
编辑:
根据daramarak在下面的回答,
我最后做的几乎与后来以稍微冗长的形式提出的abarnert相同;
vals = [x.rsplit(',', 1) for x in (data.split('='))]
ret = list()
while vals:
value = vals.pop()[0]
key = vals[-1].pop()
ret.append((key, value))
if len(vals[-1]) == 0:
break
Run Code Online (Sandbox Code Playgroud)
编辑2:
只是为了满足我的好奇心,这真的可以用纯正则表达式吗?即这样re.findall()会返回2元组的列表?
ig0*_*774 10
仅仅为了比较的目的,这里的正则表达式似乎也解决了这个问题:
([^=]+) # key
= # equals is how we tokenise the original string
([^=]+) # value
(?:,|$) # value terminator, either comma or end of string
Run Code Online (Sandbox Code Playgroud)
这里的技巧是限制你在第二组中捕获的内容..+吞下=标志,这是我们可以用来区分键和值的字符.完整的正则表达式不依赖于任何反向跟踪(因此它应该与re2之类的东西兼容,如果这是可取的)并且可以使用abarnert的示例.
用法如下:
re.findall(r'([^=]+)=([^=]+)(?:,|$)', 'foo=bar,breakfast=spam,eggs,blt=bacon,lettuce,tomato,spam=spam')
Run Code Online (Sandbox Code Playgroud)
哪个回报:
[('foo', 'bar'), ('breakfast', 'spam,eggs'), ('blt', 'bacon,lettuce,tomato'), ('spam', 'spam')]
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
9720 次 |
| 最近记录: |