在 Python 中找到一些文本后如何阅读某些行?

How to read certain lines after you find some text in Python?

提问人:user2954167 提问时间:7/14/2018 更新时间:7/14/2018 访问量:4878

问:

我正在阅读一个巨大的文件,其中包含包含我需要的信息的文本块。查找该信息的唯一方法是搜索该信息的“标题”。这是一个简单的解决方案:"text"

line1 = f.readline()
if "text" in line1:
  print(":)")

但是,我需要接下来的 14 行文本中的信息(具体来说,我需要找到的行之后的第 3、12、14 和 15 行)。目前我正在使用"text"

line2 = f.readline()
line3 = f.readline()
...
line15 = f.readline()

但这似乎效率极低。有没有更简洁的方法?我还需要能够遍历它,找到 的每个实例 ,以及后面的信息。非常感谢"text"

蟒蛇 读取线

评论

0赞 postoronnim 7/14/2018
f.readlines() 会将所有行放在一个列表中。然后,您可以遍历列表并找到所需的内容。
0赞 lenik 7/14/2018
第 5 行再次包含怎么样?你会读 8 日、17 日、19 日等等吗?text

答:

-1赞 rth 7/14/2018 #1

尝试构建一个循环并计算您的行数。有什么东西链接这个

rl = []
with opne("your_file") as fd:
  cnt = 25 #let's start outside required line number after text
  for l in fd.readlines():
     cnt += 1
     if "text" in l: # "text" in your line
       cnt = 0       # reset counter
     elif cnt in [3,12,13,14,15]: # if counter is one of lines you want
       rl.append(l)               # record them
print rl
1赞 0xsx 7/14/2018 #2

我通常使用一个循环来做这样的事情,里面嵌套了一个循环:whilefor

with open(filename) as f_in:
  while True:
    line = f_in.readline().strip()
    if not line:
      break
    if line == "text":
      data = [f_in.readline().strip() for i in range(15) if i in [2, 11, 13, 14]]

这样可以避免在处理文件之前加载整个文件,如果数据段之间可能有不需要加载的额外行,但只有在没有重叠段的情况下才能正常工作,则此功能尤其有用。

请注意,此代码将从行中去除前导和尾随空格。如果只想删除尾随空格,则可以改用。如果您想完全避免更改行,您可以尝试使用前缀匹配或简单地在您的条件中包含换行符。rstrip()startswith()

评论

0赞 lenik 7/14/2018
重叠的段怎么样?
0赞 0xsx 7/14/2018
谢谢,编辑以解决重叠段问题。
0赞 user2954167 7/14/2018
这是非常优雅的,正是我想要的。定义方式使得从我需要的读取行中获取信息变得容易。非常感谢!data
0赞 Steve Barnes 7/14/2018 #3

如果您确定不会有任何重叠的部分,则可以使用如下内容:

lineno = 0
needed = [3, 12, 14, 15] # This may need adjusting to allow for lineno running from 1
found_at = None
for line in open('filename.txt').readlines():  # This will read blocks of lines for speed
    lineno += 1  # Human readable line numbers
    if found_at:
        if (lineno - found_at) in needed:
            print(lineno, line)
        elif (lineno - found_at) > max(needed):
            found_at = None
    elif text in line:
        found_at = lineno

您也可以使用复杂的正则表达式,但可能不值得花时间构建一个正则表达式,而且不太清楚。