python基于位置和长度的ascii文件解析

2024-10-01 11:32:06 发布

您现在位置:Python中文网/ 问答频道 /正文

我想把特定的ascii文件转换成csv。 这个ascii文件有自己的规范,我在下面发布了相关的片段。
A行以代码66TP开头:

66TP        1003    54.437269600149717.012388003107655.5139691177756                :10.008677993245250.01231534739191


B线从C6NM开始:

^{pr2}$


如您所见,单个值没有分开,但它们的区别是 按位置和长度排列。在

A线规格:

1 Position   Length Data format Description of field

2   1           2   Type code   Record type code = 66
3   3           2   Derivation  Derivation code
4   5           16  Name        Point name
5   21          16  Latitude    Latitude
6   37          16  Longitude   Longitude
7   53          16  Distance    WGS84 ellipsoidal height at APC
8   69          16  Text 16     Feature code
9   85          1   GPS Method  Measurement method
10  86          1   Classification  Classification of the point
11  87          16  Distance    Horizontal precision
12  103         16  Distance    Vertical precision


B线规格:

1   Position Length Data format Description of field
2   1           2   Type code   Record type code = C6
3   3           2   Derivation  Derivation code
4   5           2   Integer 2   Minimum number of satellites
5   7           1   Boolean     Relative DOPs
6   8               16  Scalar  PDOP (maximum)
7   24          16  Scalar  HDOP (maximum)
8   40          16  Scalar  VDOP (maximum)
9   56          16  Scalar  RMS
10  72          4   Integer 4   Number of GPS positions used
11  76          16  Distance    Horizontal standard deviation
12  92          16  Distance    Vertical standard deviation
13  108         4   Integer 4   Start GPS week
14  112         16  Scalar  Start GPS time in seconds to 3dp
15  128         4   Integer 4   End GPS Week
16  132         16  Scalar  End GPS time in seconds to 3dp
17  148         1   Monitor Status


我想要的输出是合并两行,如下所示:

1003,54.4372696001497,17.0123880031076,55.5139691177756,0.009,0.012,8,1.6,0.9,1.28,20.8,033,1679,475490.0,1679,475527.0


这里是输入文件,我在这里用方括号标记了各个值:

66TP        [1003]    [54.4372696001497][17.0123880031076][55.5139691177756]                :1[0.00867799324525][0.01231534739191]

C6NM[082][1.56582379341126][0.90016734600067][1.28121149539948][20.81007696688170][033]                                [1679][475490.000000000][1679][475527.0000000001]


很抱歉我的帖子太长了,但我不知道如何才能用简短的方式来描述它。 我是一个业余的初学者程序员,我想问你任何提示,让我开始 处理此类数据。在


Tags: 文件ofdataasciipositioncodeintegerlength
3条回答

我认为使用生成器来编写这篇文章会很有启发性(可能对某些人有用)。在

首先,代码:

  1 #!/usr/bin/env python
  2
  3 def parser(str,len):
  4     '''Generate parsed chunks from str based on a list of lengths, len'''
  5     position = 0
  6     for l in len:
  7         yield str[position:position+l]
  8         position = position + l
  9
 10 line = '66TP        1003    54.437269600149717.012388003107655.5139691177756'
 11 lengths = [2, 2, 16, 16, 16, 16, 16, 16, 1, 1, 16, 16]
 12
 13 lines = [ chunk for chunk in parser(line, lengths) ]
 14 print lines

现在,您可以在任何可以使用迭代器的地方使用解析器;例如,我在第13行使用它将所有字符串放入名为lines的列表中。在

您还可以以有趣的方式更改生成器,例如在第7行末尾添加.strip()。现在,您的字段已经从每个字段的前面和后面删除了空白。在

第7行修改如下:

^{pr2}$

现在您可以得到这个修改的输出:

['66', 'TP', '1003', '54.4372696001497', '17.0123880031076', '55.5139691177756', '', '', '', '', '', '']

这看起来有点像是用空格分隔的,在这种情况下,您可以忽略列号而只使用线.分割()以获取字段列表。在

我的to table程序也可能有助于: http://stromberg.dnsalias.org/~strombrg/to-table.html

{为了知道每一行元素的位置,请使用}。在

例如

type_code = linea[0:2]
(derivation, name) = (linea[2:4], linea[4:20])

为了更进一步,您可以编写一个小函数来分割一条线,给出一个线的长度列表。在

代码

^{pr2}$

输出

['66', 'TP', '        1003    ', '54.4372696001497', '17.0123880031076', '55.5139691177756', '', '', '', '', '', '']

这只是返回一个数据元素的列表。您可以进一步提供一个变量名和每个长度([[2,'type'], [2,'derivation'],...]),并稍微改变一下函数,使其返回一个dict,这样您就可以使用the_result['variable_name']来访问它

一些想法可以玩玩。http://learnpythonthehardway.org/这对你来说是一件很好的事情,这样你就可以学习基本的语言了。在

相关问题 更多 >