我有一个包含混合纯文本的json对象的报告,如下所示:
Payload
0x0000: some text
text
{
"text1": {
"text2": {
"text3": "value3",
"text4": "value4",
"text5": "value5"
},
"text6": "value6",
"text7": "value7"
},
"text8": "value8"
}
Payload 2
0x0001: some other text
other text
{
"text1": {
"text2": {
"text3": "value3",
"text4": "value4",
"text5": "value5"
},
"text6": "value6",
"text7": "value7"
},
"text8": "value8"
}我想要做的是读取文件,提取这些json对象,并从每个对象中获取特定的值。问题是报告很大,json对象之间的纯文本并不是每次都包含相同的单词。我尝试的是使用json.loads(.)(失败)和json.dumps(.)它不会忽略这些纯文本字符串。
filedes = open(path, "r")
# Reading the whole file
text = filedes.read()
text = json.dumps(text)对于如何在不手动删除这些纯文本行的情况下解析这些文本行,有什么想法吗?
发布于 2022-08-23 20:27:46
假设在这些情况下,对象之间的随机文本永远不会匹配,在读取期间,忽略所有不以开头的行(我假设json也可以用括号出现):
(
[]{}regex示例:匹配^[^\{\}\[\] ].*$并使用nothing替换。
^匹配line[的开头将打开一个字符class^,该字符在组的开头与group\{\}\[\]中不匹配的所有内容匹配,其中每个字符都用\转义,匹配文字{}[] (包括空空间)。由于字符类被否定,所以匹配所有不是items.]的字符class.*匹配after$匹配到行末尾的所有内容。
可能您需要根据您的操作方式(引擎和输入方法组合)来避免反斜杠本身。
但是,请记住,下面这样的字符串还不是有效的json。
{
"text1": { ... },
"text8": "value8"
}
{
"text1": { ... },
"text8": "value8"
}您仍然需要拆分它自己的对象中的每个对象,或者(如下所示)将它们封装在一个数组中,并在每个对象之间添加逗号。
[{
"text1": { ... },
"text8": "value8"
},
{
"text1": { ... },
"text8": "value8"
}]因此,在第一个正则表达式中,可以用逗号代替要忽略的行,然后删除重复的逗号(将^,(\r?\n,)+$替换为, )。最后,修剪尾随和引导逗号,并添加一个领先的[和尾随的]。
^,匹配以comma(开头的行打开一个group\r?\n,匹配换行符(匹配\r\n,\r是可选的),而comma)+关闭一个组,但是由于+,所有这个组必须匹配1次或更多次(因此,在第一个逗号之后,换行符+逗号可以重复indefinitely)$匹配字符串的结尾
代码中的一个示例(使用regex101.com中的帮助生成,然后修改):
import re
regex_invalid_lines = r"^[^\{\}\[\] ].*$"
regex_duplicate_commas = r"^,(\r?\n,)+$"
test_str = ("Payload\n"
"0x0000: some text\n"
"text\n"
"{\n"
" \"text1\": {\n"
" \"text2\": {\n"
" \"text3\": \"value3\",\n"
" \"text4\": \"value4\",\n"
" \"text5\": \"value5\"\n"
" },\n"
" \"text6\": \"value6\",\n"
" \"text7\": \"value7\"\n"
" },\n"
" \"text8\": \"value8\"\n"
"}\n"
"Payload 2\n"
"0x0001: some other text\n"
"other text\n"
"{\n"
" \"text1\": {\n"
" \"text2\": {\n"
" \"text3\": \"value3\",\n"
" \"text4\": \"value4\",\n"
" \"text5\": \"value5\"\n"
" },\n"
" \"text6\": \"value6\",\n"
" \"text7\": \"value7\"\n"
" },\n"
" \"text8\": \"value8\"\n"
"}")
partial_result = re.sub(regex_invalid_lines, ",", test_str, 0, re.MULTILINE)
partial_result = re.sub(regex_duplicate_commas, ",", partial_result, 0, re.MULTILINE)
# without multiline to match literal beginning/end of string
# ^,|,$ matches both leading comma and trailing comma
partial_result = re.sub("^,|,$", "", partial_result)
result = f"[{partial_result}]"
if result:
print (result)发布于 2022-08-23 19:48:31
您可以尝试循环遍历每一行,然后写入一个单独的文件,从您的行={并在一行=}之后停止时开始。
发布于 2022-08-23 20:21:20
您需要解析整个文件并跟踪对象的边界。
import json
values = []
with open('data.txt') as f:
in_object = False
data = None
for line in f.readlines():
line = line.strip()
if line == "}":
if data is not None:
data.append(line)
content = '\n'.join(data)
values.append(json.loads(content))
in_object = False
elif line == "{":
in_object = True
data = [line]
else:
if in_object and data is not None:
data.append(line)
print(f'Found {len(values)} values')
for v in values:
print(v)https://stackoverflow.com/questions/73464359
复制相似问题