Python:检查字符串是否为JSON而不引发异常?

时间:2017-03-01 19:39:58

标签: python json performance parsing exception

我有一个字符串流,我需要分析每个字符串并检查它是否是有效的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是我所需要的。

3 个答案:

答案 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)==0if 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开头的简单字符串; {")。