将文件中的块解析为Python列表而不添加换行符

时间:2013-01-25 15:21:29

标签: python file-io python-2.7

我有一个特定的东西,在一个通用文件中有很多内容,任意长,可以包含任何字符,每行开一个空格,并在某个文本文件中有表格:

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

我对{/ 1}}和\HF=之间的特定序列感兴趣我想将这些数字放入Python列表中。这个序列只是一系列以逗号分隔的数字,然而,这些数字可以翻到第二行。此外,\RMSD=\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']

5 个答案:

答案 0 :(得分: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)

此致

过去

答案 1 :(得分: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\

答案 2 :(得分:0)

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

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

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

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

答案 3 :(得分: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']

答案 4 :(得分: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']