Python-如何使用seek()向后浏览文本文件的多行?

Python-如何使用seek()向后浏览文本文件的多行?,python,python-2.7,Python,Python 2.7,我想做的是匹配文本文件中的一个短语,然后打印那一行(这很好)。然后我需要将光标向上移动4行,以便在该行中进行另一次匹配,但我无法使seek()方法从已匹配的行向上移动4行,以便进行另一次正则表达式搜索。似乎我对seek()所能做的就是从文件的末尾或开头进行搜索。它似乎不允许我从匹配的行中搜索(105,1) ###这是示例test.txt This is 1st line This is 2nd line # Needs to seek() to this line from the 6th li

我想做的是匹配文本文件中的一个短语,然后打印那一行(这很好)。然后我需要将光标向上移动4行,以便在该行中进行另一次匹配,但我无法使seek()方法从已匹配的行向上移动4行,以便进行另一次正则表达式搜索。似乎我对seek()所能做的就是从文件的末尾或开头进行搜索。它似乎不允许我从匹配的行中搜索(105,1)

###这是示例test.txt
This is 1st line
This is 2nd line # Needs to seek() to this line from the 6th line. This needs to be dynamic as it wont always be 4 lines.
This is 3rd line
This is 4th line
This is 5th line
This is 6st line # Matches this line, now need to move it up 4 lines to the "2nd line"
This is 7 line
This is 8 line
This is 9 line
This is 10 line
#
因为您已经使用
file.readlines()
将所有内容一次读入内存
tell()。如果您仍然想要,您必须逐行读取文件,并记录每行开头在文件中的位置,以便可以返回四行

对于您描述的问题。您可以首先找到第一个匹配行的索引,然后从列表切片开始执行第二个操作,在这之前有四个项目

这里有一个非常粗略的例子(
return None
并不是真正需要的,只是为了详细起见,它清楚地说明了意图/预期行为;根据总体计划的不同,引发异常也可能是一个理想的例子):


注意,由于行是用尾随的换行符读入的,
print
会添加一个自己的行,因此在打印之前,我已经
rstrip
'。请注意。

因为您已经使用
file.readlines()
将所有内容一次读入内存
tell()。如果您仍然想要,您必须逐行读取文件,并记录每行开头在文件中的位置,以便可以返回四行

对于您描述的问题。您可以首先找到第一个匹配行的索引,然后从列表切片开始执行第二个操作,在这之前有四个项目

这里有一个非常粗略的例子(
return None
并不是真正需要的,只是为了详细起见,它清楚地说明了意图/预期行为;根据总体计划的不同,引发异常也可能是一个理想的例子):


注意,由于行是用尾随的换行符读入的,
print
会添加一个自己的行,因此在打印之前,我已经
rstrip
'。请注意。

当然
file.tell()
提供文件的结尾,您已经将整个文件读入内存:
string=file.readlines()
。由于您正在迭代一个列表(奇怪的是,您将其命名为
string
),因此您可以只使用列表索引。。。不需要弄乱文件。如果文件很小,请将其全部读入内存(您已经这样做了),并使用列表索引在行之间导航。忘记基于文件的操作,直到您
.writelines()
完成您的结果。谢谢,您介意提供一个简单的示例,我可以用它来构建吗?当然
文件。tell()
给您文件的结尾,您已经将整个文件读入内存:
字符串=文件.readlines()
。由于您正在迭代一个列表(奇怪的是,您将其命名为
string
),因此您可以只使用列表索引。。。不需要弄乱文件。如果文件很小,请将其全部读入内存(您已经这样做了),并使用列表索引在行之间导航。忘记基于文件的操作,直到你
.writelines()
得到结果。谢谢,你介意提供一个简单的示例,我可以用它来构建吗?最好添加一个测试,看看
idx>4
,否则在第一行中找到文本时,它会出错。当然,这只是一个粗略的示例。我添加了一个不匹配的测试,但您也需要检查下限。取决于在这种情况下想要的行为是什么?从第一行开始?或者这是一种表示输入中断的状态?我已经相应地扩展了这个例子…嗨,Ondrej K,谢谢你的回答,但这只是打印出除第一行以外的所有行。目标是匹配“这是第6行”并打印出该行。然后向上移动4行到第2行,并打印第2行的输出,即“这是第2行”。谢谢。是的,我不知道那背后的意图是什么。。。因此,更通用的骨架似乎更有意义。我已经添加了另一个打印的例子。谢谢你Ondrej K。这是一个非常有用的例子。我想我可以从这里开始。最好添加一个测试,看看是否
idx>4
,否则在第一行中找到该文本时会出错。当然,这只是一个粗略的示例。我添加了一个不匹配的测试,但您也需要检查下限。取决于在这种情况下想要的行为是什么?从第一行开始?或者这是一种表示输入中断的状态?我已经相应地扩展了这个例子…嗨,Ondrej K,谢谢你的回答,但这只是打印出除第一行以外的所有行。目标是匹配“这是第6行”并打印出该行。然后向上移动4行到第2行,并打印第2行的输出,即“这是第2行”。谢谢。是的,我不知道那背后的意图是什么。。。因此,更通用的骨架似乎更有意义。我已经添加了另一个打印的例子。谢谢你Ondrej K。这是一个非常有用的例子。我想我可以从这里开始。
def Findmatch():
    file = open("test.txt", "r")
    print file.tell() # shows 0 which is the beginning of the file
    string = file.readlines()

    for line in string:
        if "This is 6th line" in line:
            print line
            print file.tell() # shows 171 which is the end of the file. I need for it to be on the line that matches my search which should be around 108. seek() only lets me search from end or beginning of file, but not from the line that was matched.

Findmatch() 
def relevant(value, lines):
    found = False
    for (idx, line) in enumerate(lines):
        if value in line:
            found = True
            break # Stop iterating, last idx is a match.
    if found is True:
        idx = idx - 4
        if idx < 0:
            idx = 0  # Just return all lines up to now? Or was that broken input and fail?
        return lines[idx:]
    else:
        return None

with open("test.txt") as in_file:
    lines = in_file.readlines()

print(''.join(relevant("This is 6th line", lines)))
def print_relevant(value, lines):
    found = False
    for (idx, line) in enumerate(lines):
        if value in line:
            found = True
            print(line.rstrip('\n'))
            break # Stop iterating, last idx is a match.
    if found is True:
        idx = idx - 4
        if idx < 0:
            idx = 0  # Just return all lines up to now? Or was that broken input and fail?
        print(lines[idx].rstrip('\n'))

with open("test.txt") as in_file:
    lines = in_file.readlines()

print_relevant("This is 6th line", lines)