Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Python中解析文本文件并转换为JSON_Python_Json_Scripting - Fatal编程技术网

如何在Python中解析文本文件并转换为JSON

如何在Python中解析文本文件并转换为JSON,python,json,scripting,Python,Json,Scripting,我有一个大文件,格式如下: "string in quotes" string string string number |- …这会重复一段时间。我正在尝试将其转换为JSON,因此每个块如下所示: "name": "string in quotes" "description": "string" "info": "string" "author": "string" "year": number def emit(batched): def _quotes(q):

我有一个大文件,格式如下:

"string in quotes"
string
string
string
number
|-
…这会重复一段时间。我正在尝试将其转换为JSON,因此每个块如下所示:

"name": "string in quotes"
"description": "string"
"info": "string"
"author": "string"
"year": number
def emit(batched):
    def _quotes(q):
        return q.replace('"', '')

    def _pass(p):
        return p

    def _num(n):
        try:
            return int(n)
        except ValueError:
            return n

    for n, (name, func) in enumerate([
        ('name', _quotes),
        ('description', _pass),
        ('info', _pass),
        ('author', _pass),
        ('year', _num)
    ]):
        yield name, func(batched[n])
这就是我到目前为止所做的:

import shutil
import os
import urllib

myFile = open('unformatted.txt','r')
newFile = open("formatted.json", "w")

newFile.write('{'+'\n'+'list: {'+'\n')

for line in myFile:
    newFile.write() // this is where I'm not sure what to write

newFile.write('}'+'\n'+'}')

myFile.close()
newFile.close()

我想我可以用行号模做一些事情,但我不确定这是否是正确的方法。

我想这会奏效

import itertools
import json

with open('unformatted.txt', 'r') as f_in, open('formatted.json', 'w') as f_out:
    for name, desc, info, author, yr, ignore in itertools.izip_longest(*[f_in]*6):
        record = {
            "name": '"' + name.strip() + '"',
            "description": desc.strip(),
            "info": info.strip(),
            "author": author.strip(),
            "year": int(yr.strip()),
        }
        f_out.write(json.dumps(record))

您可以使用itertools.groupby对所有部分进行分组,然后将dicts
json.dump
json文件:

from itertools import groupby
import json
names = ["name", "description","info","author", "year"]

with open("test.csv") as f, open("out.json","w") as out:
    grouped = groupby(map(str.rstrip,f), key=lambda x: x.startswith("|-"))
    for k,v in grouped:
        if not k:
            json.dump(dict(zip(names,v)),out)
            out.write("\n")
输入:

"string in quotes"
string
string
string
number
|-
"other string in quotes"
string2
string2
string2
number2
输出:

{"author": "string", "name": "\"string in quotes\"", "description": "string", "info": "string", "year": "number"}
{"author": "string2", "name": "\"other string in quotes\"", "description": "string2", "info": "string2", "year": "number2"}
要访问,只需迭代文件并加载:

In [6]: with open("out.json") as out:
            for line in out:
                 print(json.loads(line))
   ...:         
{'name': '"string in quotes"', 'info': 'string', 'author': 'string', 'year': 'number', 'description': 'string'}
{'name': '"other string in quotes"', 'info': 'string2', 'author': 'string2', 'year': 'number2', 'description': 'string2'}

这是一个做基本工作的粗略示例

它首先使用一个生成器将输入拆分为多个批次(共6个),然后使用另一个批次将键添加到值中

import json


def read():
    with open('input.txt', 'r') as f:
        return [l.strip() for l in f.readlines()]


def batch(content, n=1):
    length = len(content)
    for num_idx in range(0, length, n):
        yield content[num_idx:min(num_idx+n, length)]


def emit(batched):
    for n, name in enumerate([
        'name', 'description', 'info', 'author', 'year'
    ]):
        yield name, batched[n]

content = read()
batched = batch(content, 6)
res = [dict(emit(b)) for b in batched]

print(res)

with open('output.json', 'w') as f:
    f.write(json.dumps(res, indent=4))
更新

使用这种方法,您可以轻松地挂接格式化函数,以便年份名称值是正确的

按如下方式扩展发射函数:

"name": "string in quotes"
"description": "string"
"info": "string"
"author": "string"
"year": number
def emit(batched):
    def _quotes(q):
        return q.replace('"', '')

    def _pass(p):
        return p

    def _num(n):
        try:
            return int(n)
        except ValueError:
            return n

    for n, (name, func) in enumerate([
        ('name', _quotes),
        ('description', _pass),
        ('info', _pass),
        ('author', _pass),
        ('year', _num)
    ]):
        yield name, func(batched[n])

从您的文件中添加一些实际数据,什么是
|-
?如何确定哪一个是名称、描述等?所有部分的格式都是这样的:“John’s Website”是John及其家人的个人网站。使用的技术包括ReactJS、Less和Django。约翰·威廉姆斯2015 |-啊,对不起,断线没用。但是
|-
只是文件是如何给出的,没有什么特别之处。它只是划分块。