Python 无法分析JSON文件中的选项卡
加载JSON文件时,我遇到了一个解析问题,这些文件中似乎包含TAB字符 当我转到并输入带有制表符的零件时:Python 无法分析JSON文件中的选项卡,python,json,Python,Json,加载JSON文件时,我遇到了一个解析问题,这些文件中似乎包含TAB字符 当我转到并输入带有制表符的零件时: { "My_String": "Foo bar. Bar foo." } 验证器投诉: Parse error on line 2: { "My_String": "Foo bar. Bar foo." ------------------^ Expecting 'STRING', 'NUMBER', 'NULL', 'TRUE', 'FALSE', '{', '['
{
"My_String": "Foo bar. Bar foo."
}
验证器投诉:
Parse error on line 2:
{ "My_String": "Foo bar. Bar foo."
------------------^
Expecting 'STRING', 'NUMBER', 'NULL', 'TRUE', 'FALSE', '{', '['
这实际上是有问题的JSON文本的复制/粘贴
我尝试用json
和simplejson
加载此文件,但没有成功。我怎样才能正确加载这个?我应该预先处理文件并用\t
或空格替换选项卡吗?还是我在这里遗漏了什么
更新:
下面是simplejson
中的一个问题示例:
foo = '{"My_string": "Foo bar.\t Bar foo."}'
simplejson.loads(foo)
JSONDecodeError: Invalid control character '\t' at: line 1 column 24 (char 23)
制表符在值之外划界空白是合法的,但不在字符串之内。改用
\t
编辑:根据您的评论,我对选项卡的实际含义感到困惑。。
制表符只是一个普通字符,如“a”或“5”或“.”或通过按键盘上的键输入的任何其他字符。它占用一个字节,其数值为9。没有反斜杠或小写字母“t”
将制表符与“a”或“5”或“.”区别开来的是,作为一个使用眼球的人,您通常无法查看文本显示并识别或计数制表符字符。从视觉上看,制表符序列与(通常较大但视觉上不确定数量的)空间序列相同
为了在计算机处理的文本中清晰地表示制表符,我们有各种语法方法来表示“嘿,某个软件!稍后用制表符替换这个垃圾,好吗?”
在编程语言的历史上,有两种主要的方法;如果回到20世纪50年代,两种方法并存,两种最古老的高级语言各有一种。Lisp对字符文本进行了命名,如#\Tab
;一旦从程序源中读取它们,它们就被转换。Fortran只有CHAR
函数,该函数在运行时被调用,并返回与参数匹配的字符:CHAR(9)
返回一个制表符。(当然,如果它真的是CHAR(9)
而不是CHAR(
某个表达式的结果是9)
,那么优化编译器可能会注意到这一点,并在编译时用一个选项卡替换函数调用,把我们放回另一阵营。)
通常,对于这两种解决方案类型,如果您想将特殊字符粘贴到更大的字符串中,您必须自己进行连接;例如,一个80年代的儿童黑客基础可能会写这样的东西:
10 PRINT "This is a tab ->"; CHR$(9); "<- That was a tab"
不是有效的JSON。Python解释器在读取字符串时立即将\t
序列转换为实际的制表符-远远早于JSON处理器看到它
通过将反斜杠加倍,可以告诉Python在字符串中放入一个文本\t
,而不是制表符:
foo = '{"My_string": "Foo bar.\\t Bar foo."}'
或者您可以使用“原始”字符串语法,它根本不解释特殊的反斜杠序列:
foo = r'{"My_string": "Foo bar.\t Bar foo."}'
无论哪种方式,JSON处理器都会看到一个包含反斜杠后跟“t”的字符串,而不是一个包含制表符的字符串。您可以通过转义将制表符包含在JSON文件的值中(而不是作为空格)。下面是Python2.7中的json
模块的工作示例:
>>> import json
>>> obj = json.loads('{"MY_STRING": "Foo\\tBar"}')
>>> obj['MY_STRING']
u'Foo\tBar'
>>> print obj['MY_STRING']
Foo Bar
不转义“\t”
时会导致错误:
>>> json.loads('{"MY_STRING": "Foo\tBar"}')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/__init__.py", line 338, in loads
return _default_decoder.decode(s)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/decoder.py", line 365, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/decoder.py", line 381, in raw_decode
obj, end = self.scan_once(s, idx)
ValueError: Invalid control character at: line 1 column 19 (char 18)
>>json.loads(“{”我的字符串“:“Foo\tBar”}”)
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
文件“/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/_init__.py”,第338行,加载
返回\u默认\u解码器。解码
文件“/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/decoder.py”,解码中的第365行
obj,end=self.raw\u decode(s,idx=\u w(s,0.end())
文件“/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/decoder.py”,第381行,原始解码
obj,end=self.scan_一次(s,idx)
ValueError:第1行第19列(字符18)处的控制字符无效
来自:
允许在任何标记之前或之后使用不重要的空格。这个
空白字符是:字符制表(U+0009),换行
(U+000A)、回车符(U+000D)和空格(U+0020)。空白是
在任何令牌中都不允许,但在
字符串
这意味着JSON字符串中不允许使用文本制表符。您需要将其转义为\t
:
此外,如果在Python字符串文本中提供json文本,则需要双转义该选项卡:
foo = '{"My_string": "Foo bar.\\t Bar foo."}' # in a Python source
或者使用Python原始字符串文字:
printf("This is a tab -> *t <- That was a tab");
foo = r'{"My_string": "Foo bar.\t Bar foo."}' # in a Python source
请分享我的经验:
我正在使用snakemake和一个用Json编写的配置文件。json文件中有用于缩进的选项卡。TAB为此目的是合法的。但我收到错误消息:snakemake.exceptions.WorkflowError:Config文件不是有效的JSON或YAML。我相信这是一只蛇虫子;但我可能错了。请评论。将所有选项卡替换为空格后,错误消息消失。在节点红色流i中,遇到相同类型的问题:
flow.set("delimiter",'"\t"');
错误:
{ "status": "ERROR", "result": "Cannot parse config: String: 1: in value for key 'delimiter': JSON does not allow unescaped tab in quoted strings, use a backslash escape" }
解决方案:
我只是在代码中添加了\\t
flow.set("delimiter",'"\\t"');
嗯,很有趣。用
\t
替换有问题的选项卡
会使JSONlint验证器在线通过,但是simplejson
抱怨:JSONDecodeError:第XXX行第YYY列(char ZZZ)处的无效控制字符“\t”
JSONDecodeError具有误导性。它发现一个无效的文本制表符。为了显示错误消息,将其转换为“\t”,而不是在屏幕上显示文字选项卡。谢谢mtitan8
。你知道官方JSON规范中是否提到/讨论过这个问题吗?或者它是特定于librari
{ "status": "ERROR", "result": "Cannot parse config: String: 1: in value for key 'delimiter': JSON does not allow unescaped tab in quoted strings, use a backslash escape" }
flow.set("delimiter",'"\\t"');