【发布时间】:2013-01-16 11:55:33
【问题描述】:
我有一个简单的“解析器”,它只是做一些类似的事情:[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 几乎相同的事情,后来suggested 做了更详细的形式;
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
编辑 2:
只是为了满足我的好奇心,这真的可以用 pure 正则表达式吗?也就是说,re.findall() 会返回一个 2 元组列表?
【问题讨论】:
-
你的预期输出是什么?
-
为什么不用分号 (foo=bar;breakfast=spam,eggs)?
-
@RohitJain 键位于
=的左侧,值位于右侧。在=的左侧始终是一个键。新的键值对也使用逗号分隔。对吗? -
mystring.split(',').split('=')?将.split('=')应用于list对象? -
@OscarMederos 对,这不是实际代码,因为它有点混乱。我会解决的。
标签: python regex parsing python-2.6