从字符串中提取字典

时间:2020-09-11 15:13:51

标签: python string dictionary

我正在调用一个函数,该函数返回包含字典的字符串。在记住第一行和最后一行可以包含“ {”和“}”的情况下,如何提取此字典。

This is a {testing string} example
This {is} a testing {string} example
{"website": "stackoverflow",
"type": "question",
"date": "10-09-2020"
}
This is a {testing string} example
This {is} a testing {string} example

我需要将此值提取为dict变量。

{"website": "stackoverflow",
"type": "question",
"date": "10-09-2020"
}

1 个答案:

答案 0 :(得分:2)

更新的答案


根据@martineau和@ekhumoro的评论,以下已编辑的代码包含一个功能,该功能搜索字符串并提取所有有效的dict。这是我以前回答的一种更健壮的方法,因为现实世界中dict的内容可能会有所不同,而这种逻辑(希望)可以解决这个问题。

示例代码:

import json
import re

def extract_dict(s) -> list:
    """Extract all valid dicts from a string.
    
    Args:
        s (str): A string possibly containing dicts.
    
    Returns:
        A list containing all valid dicts.
    
    """
    results = []
    s_ = ' '.join(s.split('\n')).strip()
    exp = re.compile(r'(\{.*?\})')
    for i in exp.findall(s_):
        try:
            results.append(json.loads(i))        
        except json.JSONDecodeError:
            pass    
    return results

测试字符串:

OP的原始字符串已更新,以添加多个dict,一个数字值(最后一个字段)和一个list值。

s = """
This is a {testing string} example
This {is} a testing {string} example
{"website": "stackoverflow",
"type": "question",
"date": 5
}
{"website": "stackoverflow",
"type": "question",
"date": "2020-09-11"
}
{"website": "stackoverflow",
"type": "question",
"dates": ["2020-09-11", "2020-09-12"]
}
This is a {testing string} example
This {is} a testing {string} example
"""

输出:

如OP所述,字符串中通常只有一个dict,因此(显然)可以使用results[0]进行访问。

>>> results = extract_dict(s)

[{'website': 'stackoverflow', 'type': 'question', 'date': 5},
 {'website': 'stackoverflow', 'type': 'question', 'date': '2020-09-11'},
 {'website': 'stackoverflow', 'type': 'question', 'dates': ['2020-09-11', '2020-09-12']}]

原始答案:


忽略此部分。尽管该代码可以工作,但它特别适合OP的要求,并且对于其他用途不可靠。

此示例使用正则表达式来确定字典开始{"和字典结束"}并提取中间,然后将字符串转换为正确的dict。随着新行的出现和正则表达式的复杂化,我只是拉平了字符串的开头。

根据@jizhihaoSAMA的评论,我已经更新为使用json.loads将字符串转换为dict,因为它更干净。如果您不想进行其他导入,则eval也可以使用,但不建议这样做。

示例代码:

import json
import re

s = """
This is a {testing string} example
This {is} a testing {string} example
{"website": "stackoverflow",
"type": "question",
"date": "10-09-2020"
}
This is a {testing string} example
This {is} a testing {string} example
"""

s_ = ' '.join(s.split('\n')).strip()
d = json.loads(re.findall(r'(\{\".*\"\s?\})', s_)[0])

>>> d
>>> d['website']

输出:

{"website": "stackoverflow", "type": "question", "date": "10-09-2020"}

'stackoverflow'