使用json格式化字符串

时间:2018-03-13 06:32:39

标签: python json

这是一个名为subtitles.ass的文件。如果你看一下,我会发现我定义了{font_size}{sentence[0}。显然我想用输入数据格式化它们。

[Script Info]
; Script generated by FFmpeg/Lavc57.107.100
ScriptType: v4.00+
PlayResX: 384
PlayResY: 288

[V4+ Styles]
Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding
Style: sorry,Arial,{font_size},&H00FFFFFF,&H000000FF,&H00000000,&H00000000,0,0,0,0,100,100,0,0,1,2,1,2,10,10,12,1


[Events]
Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text
Dialogue: 0,0:00:00.97,0:00:01.50,sorry,,0,0,0,,{sentence[0]}
Dialogue: 0,0:00:03.11,0:00:04.39,sorry,,0,0,0,,{sentence[1]}
Dialogue: 0,0:00:05.18,0:00:07.26,sorry,,0,0,0,,{sentence[2]}
Dialogue: 0,0:00:07.26,0:00:09.91,sorry,,0,0,0,,{sentence[3]}
Dialogue: 0,0:00:10.00,0:00:11.26,sorry,,0,0,0,,{sentence[4]}
Dialogue: 0,0:00:11.63,0:00:12.70,sorry,,0,0,0,,{sentence[5]}
Dialogue: 0,0:00:13.61,0:00:16.01,sorry,,0,0,0,,{sentence[6]}
Dialogue: 0,0:00:18.08,0:00:19.60,sorry,,0,0,0,,{sentence[7]}
Dialogue: 0,0:00:19.60,0:00:21.60,sorry,,0,0,0,,{sentence[8]}

首先,我从subtitles.ass读取数据。

with open(subtitles_file, 'r') as file:
    subtitles = file.read()

现在输入数据了。

{
  "font_size": "47",
  "sentences": [
   ....
  ]
}

最后我想用上面的json数据格式化字幕。简单地说,我想用47替换{font_size}。data高于json。

subtitles.format(data.get('font_size'), data.get('sentences'))

但是我收到了错误。

  

追踪(最近一次通话):     文件" iemoji.py",第17行,in       subtitles.format(data.get(' font_size'),data.get('句子'))   KeyError:' font_size'

编辑data

我加载这样的数据。

data = json.load(file)

2 个答案:

答案 0 :(得分:1)

此处的错误不是来自data.get,而是来自font_size

format字符串中使用命名参数时,必须提供具有匹配名称的关键字值。但是你只提供位置值,所以没有任何匹配。

可以通过做一些笨拙的事情来解决这个问题:

subtitles.format(font_size=data.get('font_size'),
                 sentences=data.get('sentences'))

但实际上,这正是format_map的用途:

subtitles.format_map(data)

为了将来的参考,如果您(暂时)分解表达式,那么调试这样的事情要容易得多,这样您就可以确切地看到导致异常的部分:

font_size = data.get('font_size')
sentences = data.get('sentences')
subtitles.format(font_size, sentences)

然后你会发现它是第三行,而不是第一行,它会提升KeyError,而且要弄清楚为什么会更容易。

最后,我不确定您使用data.get('font_size')而不仅仅是data['font_size']的原因。如果您将字体大小排除在数据字典之外,如果您要获取默认值而不是KeyError,那么您几乎肯定不希望该默认值为None,您?无论如何,如果 是一个很好的理由,即使可以简化:将data转换为collections.defaultdict(lambda: whatever-default-value-you-want),然后任何丢失的密钥都将具有该默认值。 (即使您将其与format_map一起使用。)

答案 1 :(得分:1)

您需要在format函数内解压缩字典以获取键值对。

尝试:

subtitles.format(**data)

这正是format_map的用途。

subtitles.format_map(data)

工作示例:

import json

subtitles = """[Script Info]
; Script generated by FFmpeg/Lavc57.107.100
ScriptType: v4.00+
PlayResX: 384
PlayResY: 288

[V4+ Styles]
Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding
Style: sorry,Arial,{font_size},&H00FFFFFF,&H000000FF,&H00000000,&H00000000,0,0,0,0,100,100,0,0,1,2,1,2,10,10,12,1


[Events]
Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text
Dialogue: 0,0:00:00.97,0:00:01.50,sorry,,0,0,0,,{sentence[0]}
Dialogue: 0,0:00:03.11,0:00:04.39,sorry,,0,0,0,,{sentence[1]}
Dialogue: 0,0:00:05.18,0:00:07.26,sorry,,0,0,0,,{sentence[2]}
Dialogue: 0,0:00:07.26,0:00:09.91,sorry,,0,0,0,,{sentence[3]}
Dialogue: 0,0:00:10.00,0:00:11.26,sorry,,0,0,0,,{sentence[4]}
Dialogue: 0,0:00:11.63,0:00:12.70,sorry,,0,0,0,,{sentence[5]}
Dialogue: 0,0:00:13.61,0:00:16.01,sorry,,0,0,0,,{sentence[6]}
Dialogue: 0,0:00:18.08,0:00:19.60,sorry,,0,0,0,,{sentence[7]}
Dialogue: 0,0:00:19.60,0:00:21.60,sorry,,0,0,0,,{sentence[8]}"""

data_str = """{
    "font_size": "47",
    "sentence": [
        "sample sentence0",
        "sample sentence1",
        "sample sentence2",
        "sample sentence3",
        "sample sentence4",
        "sample sentence5",
        "sample sentence6",
        "sample sentence7",
        "sample sentence8",
        "sample sentence9"
    ]
}"""

data = json.loads(data_str)
print(subtitles.format(**data))#or
#print(subtitles.format_map(data))