2

テキストファイルからデータを取得しようとしています。テキスト ファイル内の対象の行は、「マーカー 2」と「マーカー 3」の最後のインスタンスまで一致する行です。複数のマーカー (重複) が存在する可能性があります。「マーカー 2」の最小行数と「マーカー 3」の最大行数 - その最小/最大内のすべてのテキストが必要でした。これは機能しますが、これをpythonicの方法で、より効率的で少ないコードで行う方法を知りたいです。

同じファイルを 2 回開く必要があったのはなぜですか? そうでなければ、xreadlinesとreadlinesが競合していましたか?

file_seeklines.py

import sys

filename = sys.argv[1]

line_number = []
number = 0

## Fetch the boundary(start, end points)
f = open(filename,'r')

for line in f.xreadlines():
    number += 1
    if "marker 2" in line.strip().lower():
        line_number.append(number)
    if "marker 3" in line.strip().lower():    
        line_number.append(number)

#print line_number[0], line_number[-1]
start, end = line_number[0]-1, line_number[-1]

f.close()

## Grab the boundary 
g = open(filename,'r')

linelist = g.readlines()

try:
    for i in xrange(start, end):
        print linelist[i]
except:
    print "failed"
    pass
g.close()

file.txt

Welcome notice
------------------------
Hello there, welcome! Foo
Marker 0
hello

world

Bar
Yes!
Foo

How are ya?!

Bar

Have a great day!

Marker 1

Hello 1 2
12

MarKer 2
Hello 23
23
Marker 3
Hello 34
34

marker 2
Hello 45
45
MArker 3

出力

MarKer 2

Hello 23

23

Marker 3

Hello 34

34



marker 2

Hello 45

45

MArker 3
4

3 に答える 3

4

正規表現を使用していない理由はありますか? つまり(marker 2.*marker 3)re.DOTALLre.IGNORECASEフラグを使用します。

于 2012-05-22T16:11:41.917 に答える
4

ファイルがメモリに収まるほど大きくない場合は、正規表現アプローチを使用できます (オペレーターが貪欲read()であるという事実を利用します)。*

import re
with open(filename, 'r') as f:
    inBetween = re.search(r"Marker 2(.*)Marker 3", f.read(), re.S | re.I).group()

もう 1 つのオプションは、「マーカー 2」と「マーカー 3」の最初の出現でそれぞれ停止して、両方向に行を反復処理することです。

with open(filename, 'r') as f:
    lines = f.readlines
    for i in range(len(lines)):
        if "marker 2" in lines[i].lower():
            start = i
            break
    else:
        start = None

    for i in range(len(lines), -1, -1):
        if "marker 3" in lines[i].lower():
            end = i
            break
    else:
        end = None

    if None not in (start, end):
        inBetween = lines[start + 1:end]
    else:
        #one of the markers is missing, handle here.
于 2012-05-22T16:12:24.280 に答える
2

readlines()butを使用しないread()でください。行を反復処理する必要がなくなります。

で興味のある部分を見つけることができますsplit()

例えば

with open(filename,'r') as f:
    text = f.read().lower().split("marker 2",1)[1]
    text = text.rsplit("marker 3",1)[0]

    print('marker 2\n'+text+'marker 3')
于 2012-05-22T16:11:38.947 に答える