如何解析.dat文件而不重复结构

时间:2013-03-23 10:46:27

标签: python matlab parsing numpy

我的问题是解析Missile Datcom的输出,我不知道是否有人知道它。文件的长度是可变的。

我的目标是检索存储在这些表中的所有数据并将其保存在正确的文件结构中(我认为是MATLAB .mat文件)。我能得到的唯一对称就是重复这样的文本结构:

***** THE USAF AUTOMATED MISSILE DATCOM * REV 3/99 *****     CASE   1
           AERODYNAMIC METHODS FOR MISSILE CONFIGURATIONS          PAGE   2
               STATIC AERODYNAMICS FOR BODY-FIN SET 1

   ******* FLIGHT CONDITIONS AND REFERENCE QUANTITIES *******
 MACH NO  =       0.01                REYNOLDS NO = 2.318E+05 /M
 ALTITUDE =        0.0 M         DYNAMIC PRESSURE =      7.09 N/M**2
 SIDESLIP =      -5.00 DEG                   ROLL =      0.00 DEG     
 REF AREA =      0.006 M**2         MOMENT CENTER =     1.750 M
 REF LENGTH =     0.10 M           LAT REF LENGTH =      0.10 M

               ----- LONGITUDINAL -----     -- LATERAL DIRECTIONAL --
     ALPHA       CN        CM        CA        CY       CLN       CLL

    -15.00   -13.959    -4.106     2.661     4.031     1.817     0.565
    -12.50   -12.292    -1.954     5.103     4.302     1.267     0.449
    -10.00    -9.985    -0.720     7.148     4.600     0.677     0.253
     -7.50    -7.477    -0.030     7.516     4.833     0.143     0.073
     -5.00    -4.881     0.206     6.380     4.881    -0.206     0.000
     -2.50    -2.374     0.167     5.504     4.949    -0.509    -0.059
     -1.00    -0.933     0.069     5.287     4.965    -0.604    -0.036
      0.00     0.000     0.000     5.308     4.967    -0.623    -0.000
      1.00     0.933    -0.069     5.287     4.965    -0.604     0.036
      2.50     2.374    -0.167     5.504     4.949    -0.509     0.059
      5.00     4.881    -0.206     6.380     4.881    -0.206     0.000
      7.50     7.477     0.030     7.516     4.833     0.143    -0.073
     10.00     9.985     0.720     7.148     4.600     0.677    -0.253
     12.50    12.292     1.954     5.103     4.302     1.267    -0.449
     15.00    13.959     4.106     2.661     4.031     1.817    -0.565

     ALPHA       CL        CD      CL/CD     X-C.P.

    -15.00   -12.795     6.183    -2.069     0.294
    -12.50   -10.896     7.643    -1.426     0.159
    -10.00    -8.592     8.773    -0.979     0.072
     -7.50    -6.432     8.427    -0.763     0.004
     -5.00    -4.307     6.781    -0.635    -0.042
     -2.50    -2.132     5.602    -0.381    -0.071
     -1.00    -0.841     5.302    -0.159    -0.074
      0.00     0.000     5.308     0.000     2.298
      1.00     0.841     5.302     0.159    -0.074
      2.50     2.132     5.602     0.381    -0.071
      5.00     4.307     6.781     0.635    -0.042
      7.50     6.432     8.427     0.763     0.004
     10.00     8.592     8.773     0.979     0.072
     12.50    10.896     7.643     1.426     0.159
     15.00    12.795     6.183     2.069     0.294

您可以在其中获取与表相关的输入数据:MACH NO,ALTITUDE,SIDESLIP。

我必须为具有相同MACH NO,ALTITUDE和SIDESLIP的每组数据创建一个二维数组(表格)。

每当其中一个更改我就必须创建一个新数组。

我应该使用正则表达式来读取MACH NO,ALTITUDE和SIDESLIP广告旁边的值,检查它们是否已更改,但在我看来这是一个非常复杂的方法。你的方法是什么?

我在考虑使用Python。

2 个答案:

答案 0 :(得分:1)

编辑:下面是一段正在完成工作的代码。由于我决定研究这个主题以获得有关正则表达式的更多知识,因此最终代码中没有正则表达式,所以我最终有点沮丧。让我在下面总结解析代码的不同部分,希望有人可以帮助在正确的地方使用正则表达式 - 我发现只有一个地方正则表达式可能有用,但也许还有其他地方它可能是案件。随意评论。

1 /通过查找有字符串'FLIGHT CONDITIONS'的行将文件分成块 - 我猜没有正则表达式

2 /将一个块分成两部分:第一部分用hdr: 几行格式如下:        MACH NUMBER = 0.67 REYNOLDS NU = 2.05E5 / M. 也许这是一个正则表达式可能有用的地方: 而不是用''拆分该行,如何从这一行提取正则表达式,有用的信息可以说[('MACH NUMBER',0.67),('REYNOLDS NU',2.05E5))

3 /合并可能分割的数据数组=>我无法看出正则表达式是否有用。


这是一段正在完成工作的代码。我希望你能从它开始拥有你想要的格式。让我用几句话解释一下:

第一步是将文件拆分成块:块用FLIGHT CONDITIONS分隔。

第二步是将块拆分为hdr(存储飞行条件的详细信息)和原始数据。

航班条件的详细信息存储在dct(hdr_dct)中,原始数据存储在列表(data_lst)中,其中data_hdr描述列表中的内容。

import itertools
import sys

def parse_hdr(block) :
    """
    parsing the header of a block of data
    """
    parsed_hdr = {}
    for line in block :
        if '=' not in line :
            continue
        res = [e for e in line.split(' ') if len(e) >0] # remove white space
        match = False
        name = ''
        for e in res :
            if not match :
               if e == '=' :
                  match = True
               else :
                  name += e
            else :
               parsed_hdr[name] = float(e)
               name = ''
               match = False
    return parsed_hdr


def parse_data(block) :
    """
    parse the numerical data
    """
    hdr, res, block_id = [], [], -1
    for line in block :
        splitted_line = [e for e in line.split(' ') if len(e) > 0]
        if 'ALPHA' in splitted_line :
            hdr.extend(splitted_line)
            block_id += 1
            i_b = 0
        else :
            try :
                to_add = [float(e) for e in splitted_line]
            except :
                #print "skip : " + line
                sys.exc_clear()
                continue
            if block_id == 0 :
                res.append(to_add)
            else :
               res[i_b].extend(to_add)
            i_b += 1
    return hdr, res

def parse_block(block) :
"""
    parsing the data ofone block
"""
hdr_dct  = parse_hdr(block[:5])
data_hdr, data_lst = parse_data(block[6:])


def main() :
    block_limit ='    ******* FLIGHT CONDITIONS AND REFERENCE QUANTITIES *******'
    stt_data_lst = []
    end_data_lst = []

    with open('input.dat') as f :
       lines = f.readlines()
       for i_line, line in enumerate(lines) :
            if block_limit in line :
                stt_data_lst.append(i_line)

    end_data_lst = stt_data_lst[1:] + [-1]


    for stt, end in itertools.izip(stt_data_lst, end_data_lst) :
        parse_block([ee for ee in [e.strip() for e in lines[stt+1:end]] if len(ee) > 0])


main()

答案 1 :(得分:0)

您可以随时使用

之类的内容
fid=fopen('yourfile');
A=fread(fid);
fclose(fid);

C=regexp(char(A'),'[\s ,]','split');

C将是一个由字符串(C {1} C {2} C {3} ...)组成的单元格数组,该字符串是通过用空格分隔文件获得的。通过跟踪索引并应用str2num,您应该能够获得所需的数据。

编辑

此外,strcmp将与C一起使用。例如,如果你想找到SIDESLIP发生的单元索引,你可以做到

n=find(strcmp(C,'SIDESLIP'));