如何通过pythonically从行号边界内的文本文件中获取文本?

时间:2012-05-22 16:04:06

标签: file parsing text python

我正在尝试从文本文件中获取数据。文本文件中的感兴趣的行是那些匹配“标记2”直到“标记3”的最后一个实例的行。可以有多个标记(重复)。我想要“标记2”的最小行号和“标记3”的最大行号 - 该最小/最大值内的所有文本。虽然这有效,但我希望看到如何以pythonic方式,更高效和更少的代码来实现这一点。

为什么我要两次打开同一个文件?它是否给了我,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

3 个答案:

答案 0 :(得分:4)

你是不是只使用正则表达式?即(marker 2.*marker 3) re.DOTALLre.IGNORECASE标志。

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

另一种选择是在两个方向上迭代线,分别在第一次出现“Marker 2”和Marker 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.

答案 2 :(得分:2)

不要使用readlines(),而是使用read(),这样您就不必迭代线。

然后,您可以使用split()找到您感兴趣的部分。

E.g。

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')