如何使用Python解析使用冒号分隔的文本文件,使用不同的数据类型以及更改但一致的结构

时间:2014-06-01 16:28:15

标签: python regex parsing

我有一个数据获取器,它为我提供了一个头文件和一个数据文件,我需要解析它才能进行一些计算。头文件包含大约一百多个变量,这些变量遵循下面示例标题中的模式。

示例标题:

fileName :                              C:\Path\To\File\prefix.289.13.name.00000.ext
date :                                  2013-10-16 15:46:16.978 EDT
var1 (unit) :                           1381952777
var2 (unit) :                           [ 10000 0 0 0  ]
var3 (0.1unit) :                        400
var4 (unit):                            1.03125
var5 :                                  3
var6 (description (unit)) :
[ 1.1 -0.5 0.1 ]
[ 1.1 -0.5 0.1 ]
[ 1.1 -0.5 0.1 ]


          COMMENTS
------------------------------

var5给出var6矩阵中的行数。除了最后一种情况外,所有变量都通过冒号与它们的值分开。它们可能有也可能没有在变量名和冒号之间的括号之间指定的单位。指定单位时,有时也会在单位之前加上比例因子。值可以是字符串,日期,整数,浮点数或整数或浮点数组。最后一个值与不需要的注释部分分开几个空行。

预期输出:

fileName = C:\Path\To\File\prefix.289.13.name.00000.hdr
date = 2013-10-16 15:46:16.978 EDT
var1 = 1381952777
var2 = np.array( [10000, 0, 0, 0] )
var3 = 40.0
var4 = 1.03125
var5 = 3
var6 = np.array([1.1, -0.5, 0.1],[2.1, 0.01, 0.5],[3.2, 0.4, 1.2])

理想情况下,所有变量都会包含在字典中,但我对此很新,我会接受建议。使用变量,我将能够找到它的数据文件和维度数组,这是巨大的。

我的尝试到目前为止:

我正在使用python来解析文件。我的第一个方法是

hdr = 'C:\Path\To\File\prefix.289.13.name.00000.hdr'
with open(hdr, 'r') as header:
    for line in header:
        # Stop at the first Line Feed or Carriage Return
        if line in  ['\n', '\r\n']:
            break
        else:
            (' '.join(line.strip().split(':')).split())

这足以让我将变量名称作为列表的第一个元素,将值作为最后一个元素,只要它不是数组。它因为冒号而破坏了文件名和日期,并且由于方括号而导致数组。

我的第二次尝试涉及正则表达式:

import re
hdr = 'C:\Path\To\File\prefix.289.13.name.00000.hdr'
with open(hdr, 'r') as header:
    for line in header:
        # Stop at the first Line Feed or Carriage Return
        if line in  ['\n', '\r\n']:
            break
        else:
            m = re.search('\w*', line)
            if m:
                m.group()
            else:
                print 'No match'

通过这种方法,我成功地获得了变量名称,直到文件的最后一部分,其中向量前面没有变量名,后者输出一个空字符串。我将正则表达式更改为\w+,然后最后一部分输出向量的第一个元素的第一个数字。正是在这一点上,我向自己承认,我并不比一个被蒙住眼睛的人在piñata上挥杆。所以我在这里。

我的问题是,我应该如何解决这个问题?这是一个模糊的问题,但我在本网站上发现的有关解析的所有其他问题都有很好的格式化文件。

1 个答案:

答案 0 :(得分:1)

这是一些伪代码(假设您的标题永远不会有错误):

# I like getting the lines into a list, so I can 
# more freely manipulate the index of the line I
# am messing with.
lines = []
with open(fpath, "r") as file_in:
    lines = file_in.readlines()

out_lines = []
re_STATIC = re.compile(r"^([^\s]+)\s+:\s+(.*)$")
re_VAR    = re to detect the var name, unit multiplier and unit value
re_VAR_SIZE = re to detect a variable sized array is upon us...

for idx in lines:
    line = lines[idx]

    matches_static = re_STATIC.match(line)
    if matches_static:
        out_lines.append("%s = %s"%(matches_static.group(1), matches_static.group(2)))

    matches_regular_var = re_VAR.match(line)
    if matches_regular_var:
        ...

    matches_variable_size = re_VAR_SIZE.match(line)
    if matches_variable_size:
        var_name = matches_variable_size.group(1)
        arr_size = parseInt(matches_variable_size.group(2))

        # Here we can increment index as we see fit
        arr_list = []
        for j in range(arr_size):
            idx += 1
            arr_list.append(lines[idx])
        out_lines.append("%s = np.array(%s)"%(var_name, ",".join(arr_list))

注意:这可能有很多错误,但你应该得到一般的想法:)