1

任意の長さで、任意の文字を含めることができ、各行を空白で開始し、いくつかのテキストファイルの形式を持つ多くのコンテンツの一般的なファイルに特定のブロックがあります

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

との間にある特定のシーケンスに興味が\HF=あります\RMSD=これらの数値を Python リストに入れたいと思います。このシーケンスはカンマで区切られた一連の数字ですがこれらの数字は 2 行目に繰り越すことができます。また、改行にロールオーバーすると壊れる可能性があり \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

\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 に答える
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 に答える
0

次のようなものを使用して、すべてを1行に結合します。

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.

これには、正規表現エンジンがファイルを一度にメモリに入れなくても 1 つの長い文字列として認識できるため、大きなファイルを比較的効率的に処理できるという利点があります。

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 に答える