Python 解析换行分隔文件
我正在做一个项目,我想用Python解析一个文本文件。该文件由一些数据项组成,数据块的格式各不相同。当有新行时,会找到一个新条目。这就是我想要实现的目标:Python 解析换行分隔文件,python,fileparsing,Python,Fileparsing,我正在做一个项目,我想用Python解析一个文本文件。该文件由一些数据项组成,数据块的格式各不相同。当有新行时,会找到一个新条目。这就是我想要实现的目标: 跳过前几行(前16行) 在第16行之后,有一个换行符开始新的数据输入 阅读以下几行,直到出现新的换行符。每一行都附加到一个名为data的列表中 该列表将传递给处理进一步处理的函数 重复步骤3和4,直到文件中没有更多数据 以下是该文件的一个示例: 标题信息 更多标题信息 第1行 第2行 第3行 第4行 第5行 第6行 第7行 第8行 第9行 第
标题信息
更多标题信息
第1行
第2行
第3行
第4行
第5行
第6行
第7行
第8行
第9行
第10行
第11行
第12行
第13行
更多信息更多信息更多信息更多信息更多信息
MoreInfo2 MoreInfo2 MoreInfo2 MoreInfo2 MoreInfo2 MoreInfo2 MoreInfo2
更多信息3更多信息3更多信息3更多信息3更多信息3更多信息3
更多信息4更多信息4
字段名1 0001 0001
字段名1 0002 0002
字段名1 0003 0003
字段名1 0004 0004
字段名1 0005 0005
字段名2 0001 0001
字段名3 0001 0001
字段名4 0001 0001
字段名5 0001 0001
字段名6 0001 0001
更多信息更多信息更多信息更多信息更多信息
MoreInfo2 MoreInfo2 MoreInfo2 MoreInfo2 MoreInfo2 MoreInfo2 MoreInfo2
更多信息3更多信息3更多信息3更多信息3更多信息3更多信息3
更多信息4更多信息4
字段名1 0001 0001
字段名1 0002 0002
字段名1 0003 0003
字段名1 0004 0004
字段名1 0005 0005
字段名2 0001 0001
字段名3 0001 0001
字段名4 0001 0001
字段名5 0001 0001
字段名6 0001 0001
下面是我编写的一些代码。它能够读取第一个块并将其附加到列表中:
with open(loc, 'r') as f:
for i in range(16):
f.readline()
data = []
line = f.readline()
if line == "\n":
dataLine = f.readline()
while dataLine != "\n":
data.append(dataLine)
dataLine = f.readline()
#pass data list to function
function_call(data)
# reset data list here?
data = []
如何使其适用于完整文件?我的假设是,使用“with open”,它充当“while not end of file”。在跳过前16行之后,我尝试添加一个“while True”。
我对Python的解析功能知之甚少
感谢您在advanced中提供的任何帮助。在初始跳过后添加
而为True
,肯定会起作用。当然,你必须弄清楚所有的细节
您可以尝试扩展已有的方法,在外部循环中嵌套while
循环。但将其视为单个循环可能更容易。对于每一行,您可能只需要做三件事:
- 如果没有行,因为您处于EOF,
循环,确保处理旧的中断
(文件中的最后一个块),如果先有一个数据
- 如果是空行,则启动新的
,确保先处理旧的数据
数据
- 否则,请附加到现有的
数据
- 对f:中的行使用
,而不是重复执行
并检查的f.readline()
循环
- 用于将行迭代器转换为空行分隔行组迭代器
search()
读取示例数据:
这将导致数据结构是块的嵌套列表。每个子列表由数据文件中的
\n
分组分开。文件中的块模式是它们由以空行或文件结尾的行组组成。这个逻辑可以封装在一个生成器函数中,该函数从文件中迭代生成行块,从而简化脚本的其余部分
在下面的代码中,getlines()
是生成器函数。还请注意,将跳过文件的前17行,以到达第一个块的开头
from pprint import pformat
loc = 'parsing_test_file.txt'
def function(lines):
print('function called with:\n{}'.format(pformat(lines)))
def getlines(f):
lines = []
while True:
try:
line = next(f)
if line != '\n': # not end of the block?
lines.append(line)
else:
yield lines
lines = []
except StopIteration: # end of file
if lines:
yield lines
break
with open(loc, 'r') as f:
for i in range(17):
next(f)
for lines in getlines(f):
function(lines)
print('done')
使用测试文件输出:
函数调用时使用:
['MoreInfo MoreInfo MoreInfo\n',
'MoreInfo2 MoreInfo2 MoreInfo2 MoreInfo2 MoreInfo2 MoreInfo2\n',
'MoreInfo3 MoreInfo3 MoreInfo3 MoreInfo3 MoreInfo3\n',
“MoreInfo4 MoreInfo4\n”,
“FieldName1 0001 0001\n”,
“FieldName1 0002 0002\n”,
“FieldName1 0003 0003\n”,
“FieldName1 0004 0004\n”,
“FieldName1 0005 0005\n”,
“FieldName2 0001 0001\n”,
“FieldName3 0001 0001\n”,
“FieldName4 0001 0001\n”,
“FieldName5 0001 0001\n”,
'字段名6 0001 0001\n']
使用以下命令调用函数:
['MoreInfo MoreInfo MoreInfo\n',
'MoreInfo2 MoreInfo2 MoreInfo2 MoreInfo2 MoreInfo2 MoreInfo2\n',
'MoreInfo3 MoreInfo3 MoreInfo3 MoreInfo3 MoreInfo3\n',
“MoreInfo4 MoreInfo4\n”,
“FieldName1 0001 0001\n”,
“FieldName1 0002 0002\n”,
“FieldName1 0003 0003\n”,
“FieldName1 0004 0004\n”,
“FieldName1 0005 0005\n”,
“FieldName2 0001 0001\n”,
“FieldName3 0001 0001\n”,
“FieldName4 0001 0001\n”,
“FieldName5 0001 0001\n”,
'字段名6 0001 0001\n']
完成
First:“我的假设是使用“with open”,它充当“while not end of file”(而不是文件的结尾)。”这是错误的<代码>打开时不执行任何循环;它只是确保你打开的文件在你完成后会被关闭。更重要的是:“我尝试在跳过前16行后添加一个while True”是一个非常好的方法。如果它对你不起作用,显然你出了问题。如果您向我们展示您尝试的代码,我们可以向您展示如何修复它;如果你只是描述一下,没有人能为你做什么。你应该研究一下如何使用itertools.groupby()
,并创建一个键函数,当它自己看到一个\n
时会发生变化。例如:你需要“重复”代码块
from itertools import groupby, repeat
def search(d):
"""Key function used to group our dataset"""
return d[0] == "\n"
def read_data(filename):
"""Read data from filename and return a nicer data structure"""
data = []
with open(filename, "r") as f:
# Skip first 16 lines
for _ in repeat(None, 16):
f.readline()
# iterate through each data block
for newblock, records in groupby(f, search):
if newblock:
# we've found a new block
# create a new row of data
data.append([])
else:
# we've found data for the current block
# add each row to the last row
for row in records:
row = row.strip().split()
data[-1].append(row)
return data
from pprint import pformat
loc = 'parsing_test_file.txt'
def function(lines):
print('function called with:\n{}'.format(pformat(lines)))
def getlines(f):
lines = []
while True:
try:
line = next(f)
if line != '\n': # not end of the block?
lines.append(line)
else:
yield lines
lines = []
except StopIteration: # end of file
if lines:
yield lines
break
with open(loc, 'r') as f:
for i in range(17):
next(f)
for lines in getlines(f):
function(lines)
print('done')