如何在 Python 中检查字符串是不是是有效的 JSON?
Posted
技术标签:
【中文标题】如何在 Python 中检查字符串是不是是有效的 JSON?【英文标题】:How do I check if a string is valid JSON in Python?如何在 Python 中检查字符串是否是有效的 JSON? 【发布时间】:2011-07-27 09:10:04 【问题描述】:在 Python 中,有没有办法在尝试解析字符串之前检查它是否是有效的 JSON?
例如使用 Facebook Graph API 之类的东西,有时它会返回 JSON,有时它可能会返回一个图像文件。
【问题讨论】:
api应该设置内容类型 不能指定API调用返回什么数据?我不熟悉 Facebook API,但这听起来很奇怪。 我做过一次,但是用codegolf方式 大部分回复都是json,但是,如果你调用头像,它只会返回jpg 【参考方案1】:您可以尝试执行json.loads()
,如果您传递的字符串无法解码为JSON,则会抛出ValueError
。
一般而言,针对这种情况的“Pythonic”理念称为EAFP,因为请求宽恕比请求许可更容易。
【讨论】:
我可以看到它是如何工作的。引导我进入下一个问题。它抛出一个 ValueError。我现在想要它做的是返回有问题的字符串,以便我可以用它做其他事情。到目前为止,我只收到了错误消息和类型。 只返回你在 except 子句中传递给loads
的字符串有什么问题?
没什么问题,只是我的一个菜鸟错误。看来我只是不能调用 file.read() 两次。但我可以设置一个变量并使用它。这就是我所做的。
只是一个注释... json.loads('10') 不会抛出 ValueError 并且我确定 '10' 不是有效的 json ...
尽管规范规定 JSON 文本必须是数组或对象,但大多数编码器和解码器(包括 Python 的)都可以在“顶部”处理任何 JSON 值,包括数字和字符串. 10
是一个有效的 JSON 数字值。【参考方案2】:
如果字符串是有效的 json,则 Python 脚本示例返回布尔值:
import json
def is_json(myjson):
try:
json.loads(myjson)
except ValueError as e:
return False
return True
哪些打印:
print is_json("") #prints True
print is_json("asdf") #prints False
print is_json(' "age":100') #prints True
print is_json("'age':100 ") #prints False
print is_json("\"age\":100 ") #prints True
print is_json('"age":100 ') #prints True
print is_json('"foo":[5,6.8],"foo":"bar"') #prints True
将 JSON 字符串转换为 Python 字典:
import json
mydict = json.loads('"foo":"bar"')
print(mydict['foo']) #prints bar
mylist = json.loads("[5,6,7]")
print(mylist)
[5, 6, 7]
将 python 对象转换为 JSON 字符串:
foo =
foo['gummy'] = 'bear'
print(json.dumps(foo)) #prints "gummy": "bear"
如果您想访问低级解析,请不要自行开发,请使用现有库:http://www.json.org/
python JSON 模块的精彩教程:https://pymotw.com/2/json/
是字符串 JSON 并显示语法错误和错误消息:
sudo cpan JSON::XS
echo '"foo":[5,6.8],"foo":"bar" bar' > myjson.json
json_xs -t none < myjson.json
打印:
, or expected while parsing object/hash, at character offset 28 (before "bar
at /usr/local/bin/json_xs line 183, <STDIN> line 1.
json_xs
具有语法检查、解析、prittifying、编码、解码等功能:
https://metacpan.org/pod/json_xs
【讨论】:
您认为我们应该在验证后del json_object
吗?
为什么没有合适的验证方法?应该有一种方法可以在不杀死金丝雀的情况下进行错误检查。
我的意思是:仅仅因为 Python 允许 OO 并不意味着可以忽略其他部分。我应该选择 A. 让函数失败并使用异常(OO/Python 方式),或者 B. 调用返回值(成功或错误)而不是抛出异常的函数,然后使用我的函数,反过来,返回一个指示错误的标记值,以便错误在调用堆栈中冒泡,并且可以根据需要使用(过程/C方式)。就像 C++ 不强制你使用异常(你可以使用 errno)一样,Python 也不应该强制它
@BradenBest JSON 字符串验证被使停止问题变得有趣的恶魔所困扰。没有数学上正确的方法来证明字符串的正确性,除了用解析器尝试你的字符串并查看它是否完成时没有错误。要了解为什么很难:“给我写一个程序,证明计算机程序中不存在语法错误”。那是不可能的。语言开发人员会对编码和解码的永恒军备竞赛充满诗意。如果字符串对给定引擎有效,我们能做的最好的事情是返回是/否,而不是对所有可能的引擎。
@EricLeschinski 但这里没有停止问题。如果在解析 JSON 时发生错误,程序显然会引发异常。因此,程序知道 JSON 输入何时无效。因此,无需使用try
,就可以100% 拥有一个检查输入是否有效的函数。 #StopCanaryAbuse【参考方案3】:
我想说解析它是您真正可以完全分辨的唯一方法。如果格式不正确,python 的 json.loads()
函数(几乎可以肯定)将引发异常。但是,您示例的目的可能只是检查前几个非空白字符...
我不熟悉 facebook 发回的 JSON,但大多数来自 Web 应用程序的 JSON 字符串都以开方 [
或大括号 开头。我所知道的没有图像格式以这些字符开头。
相反,如果您知道可能会显示哪些图像格式,则可以检查字符串的开头以获取其签名以识别图像,如果不是图像,则假定您有 JSON。
另一个识别图形而不是文本字符串的简单技巧,如果你正在寻找一个图形,只是在字符串的前几个字符中测试非 ASCII 字符(假设JSON 是 ASCII)。
【讨论】:
【参考方案4】:我想出了一个通用的、有趣的解决方案来解决这个问题:
class SafeInvocator(object):
def __init__(self, module):
self._module = module
def _safe(self, func):
def inner(*args, **kwargs):
try:
return func(*args, **kwargs)
except:
return None
return inner
def __getattr__(self, item):
obj = getattr(self.module, item)
return self._safe(obj) if hasattr(obj, '__call__') else obj
你可以像这样使用它:
safe_json = SafeInvocator(json)
text = "'foo':'bar'"
item = safe_json.loads(text)
if item:
# do something
【讨论】:
我认为通用解决方案很好,但在这种情况下,except
子句可能会隐藏任何严重的异常。捕获异常必须尽可能严格。【参考方案5】:
在 try 块中非常简单。然后,您可以验证正文是否是有效的 JSON
async def get_body(request: Request):
try:
body = await request.json()
except:
body = await request.body()
return body
【讨论】:
以上是关于如何在 Python 中检查字符串是不是是有效的 JSON?的主要内容,如果未能解决你的问题,请参考以下文章
如何检查字符串是不是是android中的有效电子邮件? [复制]
如何检查给定的字符串是不是是 Windows 下的合法/有效文件名?
在过程宏中,如何检查字符串是不是是有效的变量名而不是关键字?