如何从python中的不规则格式的数据文件中提取数据

时间:2010-06-21 16:02:14

标签: python parsing

2 个答案:

答案 0 :(得分:1)

我可能会这样做:

  • 迭代输出中的行
  • 搜索包含eng_tot的内容:
    • if 'eng_tot' in line.split(): process_blocks
  • 吞噬线条直到一条线符合所有破折号(两边都有可选空格)
    • if re.match("\s+-+\s+", line): proccess_metrics_block
  • 处理第一行指标:
    • 将第一列从行中删除(这使得解析更难,因为它可能不存在)
      • sanitized_line = line[8:]
      • eng_total = line.split()[0],第一列现在是eng_total
  • 跳过行,直到到达另一行破折号,然后重新开始

看到您的修改后:

  • 您需要导入文件顶部的re(正则表达式)模块:import re
  • process_blocksprocess_metrics_block是伪代码。除非您定义它们,否则它们不存在。 :)你不需要那些功能,你可以使用基本循环(while)和条件(if)语句来避免它们。
  • 你必须确保你理解你在做什么,而不仅仅是从堆栈溢出中复制! :)

看起来你正试图做这样的事情。它似乎有效,但我确信通过一些努力,你可以想出更好的东西:

import re

def find_header(lines):
  for (i, line) in enumerate(lines):
    if 'eng_tot' in line.split():
      return i
  return None

def find_next_separator(lines, start):
  for (i, line) in enumerate(lines[start+1:]):
    if re.match("\s*-+\s*", line):
      return i + start + 1
  return None

if __name__ == '__main__':
  totals = []
  lines = open('so.txt').readlines()

  header = find_header(lines)
  start = find_next_separator(lines, header+1)

  while True:
    end = find_next_separator(lines, start+1)
    if end is None: break

    # Pull out block, after line of dashes.
    metrics_block = lines[start+1:end]

    # Pull out 2nd column from 1st line of metrics.
    eng_total = metrics_block[0].split()[1]
    totals.append(eng_total)

    start = end

  print totals

您可以使用生成器更加pythonic:

def metric_block_iter(lines):
  start = find_next_separator(lines, find_header(lines)+1)
  while True:
    end = find_next_separator(lines, start+1)
    if end is None: break
    yield (start, end)
    start = end


if __name__ == '__main__':
  totals = []
  lines = open('so.txt').readlines()

  for (start, end) in metric_block_iter(lines):
    # Pull out block, after line of dashes.
    metrics_block = lines[start+1:end]

    # Pull out 2nd column from 1st line of metrics.
    eng_total = metrics_block[0].split()[1]
    totals.append(eng_total)

  print totals

答案 1 :(得分:0)

您需要明确定义文件格式,然后您应该能够轻松解析它。

第一步是确定所需数据的定义位置。然后抛弃一切到那一点。然后开始阅读。

如果eng_tot可以移动,您需要确定它在有用数据块中的位置。因此,读取一行entries = line.split(); location = entries.index('eng_tot'),然后从输出数据中相关行中的该位置读取该条目。

关键是你需要将问题分解为你知道可以做的步骤。当看到新的东西时,很容易被淹没。如果你可以开始做某事,你会发现你可以毫不费力地找到解决方案。