Python 条状\";仅来自文本文件中的某些行

Python 条状\";仅来自文本文件中的某些行,python,Python,我有一个如下组织的文本文件: NAME: name\n AGE: age\n NOTES: random text\n JOB: text \n NAME: name\n AGE: age\n NOTES: random text\n JOB: text \n 我只为每个数据块写了5行,但假设我有7行或更多行。我在这里也只写了2个块,但我的文件可能包含100多个块,我想要的输出是列表列表列表(最好是): 我通过此代码获得: list_of_lists = [list[x:x+4] for x

我有一个如下组织的文本文件:

NAME: name\n
AGE: age\n
NOTES: random text\n
JOB: text
\n
NAME: name\n
AGE: age\n
NOTES: random text\n
JOB: text
\n
我只为每个数据块写了5行,但假设我有7行或更多行。我在这里也只写了2个块,但我的文件可能包含100多个块,我想要的输出是列表列表列表(最好是):

我通过此代码获得:

list_of_lists = [list[x:x+4] for x in range(0, len(list),4)]
但我的问题是,有时
随机文本
进入
注释:
包含额外的
\n
,可能导致分组错误:

list=[[NAME: name\n, AGE: age\n, NOTES: unwanted\n, newlines\n], [that ruin\n, my plans\n, \n, NAME: name\n] etc etc]
所以基本上所有的行都是可以的,问题是NOTES,其中人们插入了一些我不想要的回车,因为他们将文本分成注释,并将其拆分为文本中的不同行和列表中的不同项目:我想删除\n以便将注释字段分组为一行(文本中)和一个项目(在列表中)

编辑:谢谢你的帮助!我尝试了你的一些解决方案,但仍然没有解决我的问题…所以我编辑了我的问题以更好地解释(以粗体编辑内容)


我建议做一些不同的事情:

result = []
d = {}
with open("file.txt") as f:
    for line in f:
        if line.startswith("NAME:"):
            if d:
                result.append(d)
            d = {}
        if any(line.startswith(key) for key in ("NAME:", "AGE:", "NOTES:")):
            key, value = line.strip().split(":", 1)
            d[key] = value
        else:
            d["NOTES"] += d["NOTES"] + line.strip()
    result.append(d)
这返回类似于

[{'NOTES': ' random text random text', 'AGE': ' age', 'NAME': ' name'}, {'NOTES': ' random text random textother text. random text random textother text.', 'AGE': ' age', 'NAME': ' name'}]

我建议做一些不同的事情:

result = []
d = {}
with open("file.txt") as f:
    for line in f:
        if line.startswith("NAME:"):
            if d:
                result.append(d)
            d = {}
        if any(line.startswith(key) for key in ("NAME:", "AGE:", "NOTES:")):
            key, value = line.strip().split(":", 1)
            d[key] = value
        else:
            d["NOTES"] += d["NOTES"] + line.strip()
    result.append(d)
这返回类似于

[{'NOTES': ' random text random text', 'AGE': ' age', 'NAME': ' name'}, {'NOTES': ' random text random textother text. random text random textother text.', 'AGE': ' age', 'NAME': ' name'}]

看起来这是一个键值对,因此首先尝试将数据拆分为一个字典列表

您可以使用
text[::-1]
反转文本文件字符串,然后执行替换
reverse_text.split(':EMAN')
,然后再次反转列表中的字符串。这将为您提供一个列表,以便解析为dict,如下所示:

list = [
    ['NAME: name\n AGE: age\n NOTES: random text\n\n'],
    ['NAME: name\n AGE: age\n NOTES: random text\n\n'],
    ...,
    ]

看起来这是一个键值对,因此首先尝试将数据拆分为一个字典列表

您可以使用
text[::-1]
反转文本文件字符串,然后执行替换
reverse_text.split(':EMAN')
,然后再次反转列表中的字符串。这将为您提供一个列表,以便解析为dict,如下所示:

list = [
    ['NAME: name\n AGE: age\n NOTES: random text\n\n'],
    ['NAME: name\n AGE: age\n NOTES: random text\n\n'],
    ...,
    ]
您可以使用列表理解来实现它,如下所示:

其中
my_list
将保存:

[['NAME: name\n', 'AGE: age\n', 'NOTES: random text\n', '\n'], ['NAME: name\n', 'AGE: age\n', 'NOTES: random text\n', '\n\n', '\n']]
如果您不想将
\n\n
作为最后一个子列表中的第二个最后一个元素,可以将其明确删除为:

del my_list[-1][-2]
现在,您的
my_列表将保存以下值:

[['NAME: name\n', 'AGE: age\n', 'NOTES: random text\n', '\n'], ['NAME: name\n', 'AGE: age\n', 'NOTES: random text\n', '\n']]
您可以使用列表理解来实现它,如下所示:

其中
my_list
将保存:

[['NAME: name\n', 'AGE: age\n', 'NOTES: random text\n', '\n'], ['NAME: name\n', 'AGE: age\n', 'NOTES: random text\n', '\n\n', '\n']]
如果您不想将
\n\n
作为最后一个子列表中的第二个最后一个元素,可以将其明确删除为:

del my_list[-1][-2]
现在,您的
my_列表将保存以下值:

[['NAME: name\n', 'AGE: age\n', 'NOTES: random text\n', '\n'], ['NAME: name\n', 'AGE: age\n', 'NOTES: random text\n', '\n']]
这是通过执行两个正则表达式搜索来实现的。第一个正则表达式查找从
名称:
开始直到下一个
名称:
或文件结尾之前的所有文本。这实际上是将文本拆分为每个人的数据。然后,使用几乎相同的正则表达式将每个文本拆分为每个属性的列表(
名称
年龄
作业
等)。此正则表达式假定每个属性标签都包含在所有大写字母中,出现在行首,后跟一个

上例中的
my_list
内容如下:

[['NAME: name\n', 'AGE: age\n', 'NOTES: random text\n\n'],
 ['NAME: name\n',
  'AGE: age\n',
  'JOB: job\n',
  'NOTES: random text\n\nblah \n\n blah\n\n'],
 ['NAME: name\n', 'AGE: age\n', 'NOTES: more \n random\n text\n\n']]
这是通过执行两个正则表达式搜索来实现的。第一个正则表达式查找从
名称:
开始直到下一个
名称:
或文件结尾之前的所有文本。这实际上是将文本拆分为每个人的数据。然后,使用几乎相同的正则表达式将每个文本拆分为每个属性的列表(
名称
年龄
作业
等)。此正则表达式假定每个属性标签都包含在所有大写字母中,出现在行首,后跟一个

上例中的
my_list
内容如下:

[['NAME: name\n', 'AGE: age\n', 'NOTES: random text\n\n'],
 ['NAME: name\n',
  'AGE: age\n',
  'JOB: job\n',
  'NOTES: random text\n\nblah \n\n blah\n\n'],
 ['NAME: name\n', 'AGE: age\n', 'NOTES: more \n random\n text\n\n']]

\n
字符实际上不是行的一部分,但如果不是以
名称:
年龄:
,或
注释:
,则可以查看每行的开头,并将其附加到前一行。但我建议将其全部放在字典中。@L3viathan-
\n
字符确实是t的一部分这是一行。它是一个像其他任何字符一样的字符。@TigerhawkT3虽然它是一个像其他字符一样的字符,但它是使行在第一位的原因。例如在
注释中:这是第二行
\n
不可能被视为第一行的一部分。在有问题的情况下,
注释的内容是什么:
。您可以首先拆分带有“\n\n”的文本。这将为您提供文本块,然后根据需要从每个文本块中获取每一行。它用作哨兵值,但它与其他字符一样是一个字符,并且是其所在行的一部分。没有行,然后是换行符,然后是换行符,然后是换行符,等等-每一行都有换行符er在结尾,它定义了行。
\n
字符实际上不是行的一部分,但是如果不是以
名称:
年龄:
,或者
注释:
开头,你可以查看每行的开头,并将其附加到前一行中。但是我建议把它们都放在字典中。@L3viathan-the
\n
字符确实是它所在行的一部分。它与其他任何字符一样。@TigerhawkT3虽然它是一个与其他字符一样的字符,但正是它使行成为第一行。例如,在
注释中:这\n\n测试
第二行
\n
不可能被视为第一行的一部分。在有问题的情况下,什么是共同的
的内容注意:
。您可以先用“\n\n”拆分文本。这将为您提供文本块,然后根据需要从每个块中获取每一行。它用作哨兵值,但它与其他字符一样,是其所在行的一部分。没有行,然后是换行,然后是换行,然后是换行,等等每一行都有一个换行符