1

在一个包含许多内容的通用文件中有一个特定的内容块,该文件任意长,可以包含任何字符,每行以空格开头,并且在某些文本文件中具有以下形式:

 1\1\GINC-NODE9999\Scan\...
 ... ... ... ... ... ... ...
 ... ... ... ... ...\HF=-568
 .8880019,-568.2343213, -568
 .2343432, ... , -586.328492
 1\RMSD=...

我对\HF=位于和之间的特定序列感兴趣\RMSD=我想将这些数字放入 Python 列表中。此序列只是一系列以逗号分隔的数字,但是,这些数字可以翻转到第二行。ALSO,\HF=并且\RMSD可以通过滚动到换行符来打破。

目前的努力

我目前有以下内容:

    with open(infile) as data:
        d1 = []
        start = '\\HF'     
        end = 'RMSD'
        should_append = False
        for line in data:
            if start in line:
                data = line[len(start):]
                d1.append(data)
                should_append=True
            elif end in line:
                should_append = False
                break
            elif should_append:
                d1.append(line)

吐出以下列表

['.6184082129,7.5129238742\\\\Version=EM64L-G09RevC.01\\
State=1-A\\HF=-568\n', ' .8880019,-568.8879907,-568.8879686,
-568.887937,-\n']

问题不仅在于我在整个过程中都有换行符,而且我还保留了比我应该的更多的数据。此外,滚动到其他行的数字在列表中具有自己的位置。我需要它看起来像

['-568.8880019', '-568.8879907', ... ]
4

5 回答 5

1

对于快速解决方案,您可以基于正则表达式实现简单的字符串连接。

我为您的数据格式实施了一个简短的解决方案。

import re

def naiveDecimalExtractor(data):
    p = re.compile("(-?\d+)[\n\s]*(\d+\.\d+)[\n\s]*(\d+)")
    brokenNumbers = p.findall(data)

    return ["".join(n) for n in brokenNumbers]

data = """
1\1\GINC-NODE9999\Scan\...
 ... ... ... ... ... ... ...
 ... ... ... ... ...\HF=-568
 .8880019,-568.2343213, -568
 .2343432, ... , -586.328492
 1\RMSD=...
"""

print naiveDecimalExtractor(data)

问候,

和过去

于 2013-01-25T15:36:10.303 回答
1

多行非贪婪正则表达式可用于提取介于 \HF= 和 \RMSD= 之间的文本。提取文本后,应该很容易将其标记为组成数字

import re
import os
pattern = r'''\HF=(.*?)\RMSD='''
pat = re.compile(pattern, re.DOTALL)
for number in pat.finditer(open('file.txt').read()):
    print number.group(1).replace(os.linesep, '').replace(' ', '').strip(r'''\\''')
... 
-568 .8880019,-568.2343213, -568 .2343432, ... , -586.328492 1\
于 2013-01-25T15:44:44.723 回答
0

使用类似这样的东西将所有内容加入一行:

with open(infile) as data:
    joined = ''.join(data.read().splitlines())

然后解析它而不用担心换行符。

如果您的文件非常大,您可能需要考虑另一种方法来避免将其全部存储在内存中。

于 2013-01-25T15:34:59.377 回答
0

像这样的东西怎么样:

# open the file to read
f = open("test.txt")

# read the whole file, then concatenate the list as one big string (str)
str = " ".join(f.readlines())

# get the substring between \HF= and \RMDS, then remove any '\', 'n', or ' '
values = str[str.find("\HF=")+5:str.find("\RMSD")].translate(None, "\n ")

# the string is now just numbers separated by commas, so split it to a list
# using the ',' deliminator 
list = values.split(',')

现在列表有:

['568.8880019', '-568.2343213', '-568.2343432', '...', '-586.3284921']
于 2013-01-25T15:52:33.730 回答
0

我有这样的东西打开并忘记发布 - 一个“稍微”不同的答案,它使用mmap'd 文件和re.finditer

这样做的好处是可以相对有效地处理较大的文件,因为它允许正则表达式引擎将文件视为一个长字符串,而不会立即进入内存。

import mmap
import re

with open('/home/jon/blah.txt') as fin:
    mfin = mmap.mmap(fin.fileno(), 0, access=mmap.ACCESS_READ)
    for match in re.finditer(r'\\HF=(.*?)\\RMSD=', mfin, re.DOTALL):
        print match.group(1).translate(None, '\n ').split(',')

# ['-568.8880019', '-568.2343213', '-568.2343432', '...', '-586.3284921']
于 2013-01-25T17:52:30.743 回答