我有一个特定的东西,在一个通用文件中有很多内容,任意长,可以包含任何字符,每行开一个空格,并在某个文本文件中有表格:
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']
答案 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']