我有一个字符串,可以是以下两种形式之一:
name multi word description {...}
或
name multi word description [...]
其中{...}
和[...]
是任何有效的JSON。我有兴趣解析字符串的JSON部分,但我不确定最好的方法(特别是因为我不知道字符串中的哪两种形式)。这是我目前的方法:
import json
string = 'bob1: The ceo of the company {"salary": 100000}'
o_ind = string.find('{')
a_ind = string.find('[')
if o_ind == -1 and a_ind == -1:
print("Could not find JSON")
exit(0)
index = min(o_ind, a_ind)
if index == -1:
index = max(o_ind, a_ind)
json = json.loads(string[index:])
print(json)
它有效,但我无法帮助,但感觉可以做得更好。我想也许正则表达式,但我遇到了匹配子对象和数组的问题,而不是最外面的json对象或数组。有什么建议吗?
答案 0 :(得分:5)
您可以通过检查{
或[
的存在来找到JSON的开头,然后将字符串末尾的所有内容保存到捕获组中:
>>> import re
>>> string1 = 'bob1: The ceo of the company {"salary": 100000}'
>>> string2 = 'bob1: The ceo of the company ["10001", "10002"]'
>>>
>>> re.search(r"\s([{\[].*?[}\]])$", string1).group(1)
'{"salary": 100000}'
>>> re.search(r"\s([{\[].*?[}\]])$", string2).group(1)
'["10001", "10002"]'
此处\s([{\[].*?[}\]])$
分解为:
\s
- 单个空格字符[{\[]
会匹配单个{
或[
(后者需要使用反斜杠进行转义).*?
是任意次数的 non-greedy 匹配[}\]]
会匹配单个}
和]
(后者需要使用反斜杠进行转义)$
表示字符串的结尾或者,您可以使用re.split()
将字符串拆分为空格,然后是{
或[
(前面是肯定的)并获取最后一项。它适用于您提供的样本输入,但不确定这是否可靠:
>>> re.split(r"\s(?=[{\[])", string1)[-1]
'{"salary": 100000}'
>>> re.split(r"\s(?=[{\[])", string2)[-1]
'["10001", "10002"]'
答案 1 :(得分:3)
您可以在正则表达式中使用简单的|
来匹配所需的子字符串:
import re
import json
def json_from_s(s):
match = re.findall(r"{.+[:,].+}|\[.+[,:].+\]", s)
return json.loads(match[0]) if match else None
还有一些测试:
print json_from_s('bob1: The ceo of the company {"salary": 100000}')
print json_from_s('bob1: The ceo of the company ["salary", 100000]')
print json_from_s('bob1')
print json_from_s('{1:}')
print json_from_s('[,1]')
输出:
{u'salary': 100000}
[u'salary', 100000]
None
None
None