我有一个字符串流,我需要分析每个字符串并检查它是否是有效的JSON。 pythonic方式(EAFP)决定了这样的事情:
THREE.ShaderChunk[(chunk name)]
问题是大量的字符串不是JSON,而且这个代码引发的许多异常会使这个过程相当缓慢。
我正在寻找一些尝试将文本解析为JSON的方法,返回某种预定义的值(例如空import json
def parse_json(string):
try:
return json.loads(string)
except:
return string
),表明字符串不是JSON兼容的。
如果这是最简单的解决方案,我不介意在标准的json包中进行黑客攻击(覆盖一两个函数..)。
有什么建议吗?
更新: 因为我只对复杂的'感兴趣。 JSON(数组和对象),我最终决定使用简单的if检查字符串的第一个和最后一个字符:
tuple()
ujson是一种比Python的标准json更高效的实现。此外,跳过未使用[]或{}包装的所有字符串可以减少异常数量。事实证明,混合LBYL和EAFP是我所需要的。
答案 0 :(得分:0)
对于速度问题,您可以使用多处理来加速解析,例如,通过在多处理中使用5个工作人员,您一次解析5个字符串而不是一个
如果我理解问题的第二部分,对于自定义异常执行类似这样的操作来获取由json返回的不同错误的自定义错误:
def parse_json(string):
try:
return json.loads(string)
except exception1 as ex1:
print(ex1)
return string
except exception2 as ex2:
print(ex2)
return string
exc....
或者如果您不想在错误提升方面获得任何异常,请执行此操作,只是给它一个通行证,什么都不做,不显示任何内容:
def parse_json(string):
try:
return json.loads(string)
except exception1 as ex1:
pass
答案 1 :(得分:0)
更紧凑的方式应该是这样。 Json lib仅处理str,byte或bytearray结构,因此仅考虑它们。对于长字符串,if len(text)==0
比if not text
快得多,我们不想知道文本的长度。 Json库可能会引发JsonDecoderError。可以使用正则表达式检查文本的倒数第二个字符,但是我尝试了可能的边缘情况,例如'{]'和'[}',它们不会失败。
def is_json(text: str) -> bool:
from json import loads, JSONDecodeError
if not isinstance(text, (str, bytes, bytearray)):
return False
if not text:
return False
text = text.strip()
if text[0] in {'{', '['} and text[-1] in {'}', ']'}:
try:
loads(text)
except (ValueError, TypeError, JSONDecodeError):
return False
else:
return True
else:
return False
编辑:我们应该检查文本是否为空,而不是引发IndexError。
def is_json(text: str) -> bool:
if not isinstance(text, (str, bytes, bytearray)):
return False
if not text:
return False
text = text.strip()
if text:
if text[0] in {'{', '['} and text[-1] in {'}', ']'}:
try:
loads(text)
except (ValueError, TypeError, JSONDecodeError):
return False
else:
return True
else:
return False
return False
答案 2 :(得分:-3)
如果字符串是JSON,则应以" {"并以"}"结束。
我认为你可以先检查字符串是否以" {";如果没有,你肯定知道它是一个简单的字符串;如果它以" {"你可以解析它并使用try / except(只是为了确保它不仅仅是一个以&#34开头的简单字符串; {")。