将带有嵌入括号的字符串转换为字典

时间:2015-05-28 06:12:15

标签: python regex dictionary

从字符串构建字典的最佳方法是什么,如下所示:

"{key1 value1} {key2 value2} {key3 {value with spaces}}"

所以键总是一个没有空格的字符串,但是值是字符串或大括号中的字符串(它有空格)?

你怎么会把它变成:

{'key1': 'value1',   'key2': 'value2',   'key3': 'value with spaces'}

4 个答案:

答案 0 :(得分:18)

import re
x="{key1 value1} {key2 value2} {key3 {value with spaces}}"
print dict(re.findall(r"\{(\S+)\s+\{*(.*?)\}+",x))

你可以试试这个。

输出:

{'key3': 'value with spaces', 'key2': 'value2', 'key1': 'value1'}

我们通过re.findall提取key及其valuere.findall返回包含所有键值对的元组的列表。在列表中使用dict元组提供了最终答案。 Read more here.

答案 1 :(得分:4)

我无法做得更优雅:

input = "{key1 value1} {key2 value2} {key3 {value with spaces}}"
x = input.split("} {")             # creates list with keys and values
y = [i.split(" {") for i in y]     # separates the list-values from keys
# create final list with separated keys and values, removing brackets
z = [[i.translate(None,"{").translate(None,"}").split() for i in j] for j in y]

fin = {}
for i in z:
    fin[i[0][0]] = i[-1]

非常hacky,但它应该可以胜任。

答案 2 :(得分:2)

假设你的字符串中没有任何东西比你的例子更嵌套,你可以先使用lookahead / lookbehind断言将字符串拆分成你的键值对,寻找模式{{ 1}}(一对括号的末尾和另一对括号的开头。)

SDKROOT

这表示&#34;匹配任何} {(空白),其前面有>>> str = '{key1 value1} {key2 value2} {key3 {value with spaces}}' >>> pairs = re.split('(?<=})\s*(?={)', str) ,后面有\s*,但不包含这些括号比赛本身。&#34;

然后你有你的键值对:

}

可以在{参数设置为1的空格上拆分,以确保它只在第一个空格上拆分。在这个例子中,我还使用了字符串索引(>>> pairs ['{key1 value1}', '{key2 value2}', '{key3 {value with spaces}}'] )来消除我知道在每对的开头和结尾的花括号。

maxsplit

然后只需检查该值是否包含在花括号中,如果需要,请在将它们放入词典之前将其删除。

如果确保键/值对总是由单个空格字符分隔,那么您可以使用普通的旧字符串拆分。

[1:-1]

答案 3 :(得分:1)

@vks的答案并没有检查平衡的大括号。请尝试以下方法:

>>> x="{key3 {value with spaces} {key4 value4}}"
>>> dict(re.findall(r"\{(\S+)\s+\{*(.*?)\}+",x))
{'key3': 'value with spaces', 'key4': 'value4'}

尝试改为:

>>> dict(map(lambda x:[x[0],x[2]], re.findall(r'\{(\S+)\s+(?P<Brace>\{)?((?(Brace)[^{}]*|[^{}\s]*))(?(Brace)\})\}',x)))
{'key4': 'value4'}

也就是说,它只与具有正确支撑的部分匹配。

(?P<Brace>\{)保存{的匹配,后来(?(Brace)\})只会匹配},只有第一个匹配,因此大括号必须匹配对。通过(?(Brace)...|...)构造,如果\Brace匹配,则值部分可以包含除大括号([^{}]*)之外的任何内容,否则不允许空格([^{}\s]*)。

由于可选括号在正则表达式中匹配,因此在列表中返回,我们需要通过map()函数从每个列表中提取元素0和2。

正则表达式很容易变得混乱。