【问题标题】:read snippet of file with regular expressions from text file in python从python中的文本文件中读取带有正则表达式的文件片段
【发布时间】:2012-03-28 23:00:30
【问题描述】:

我有一个文本文件,我想在其中使用正则表达式匹配单词 PATTERN 并提取 STARTEND 之间的文本(文本文件如下所示)。我不想直接匹配STARTEND 字段,因为我在该部分中有随机数据,但PATTERN 保持不变,因此我可以轻松匹配它。我有一个可以匹配模式的快速而肮脏的 Python 脚本,但我被困在下一步。

HERE IS MY PATTERN:


        IGNORE SECTION

**************************************************
START   1   2   3   4   5
  .     .   .   .   .   .
  .     .   .   .   .   .
  .     .   .   .   .   .
END     .   .   .   .   .



TEXT    FILE    CONTINUES...........
.
.
.
.

**************************************************

我如何告诉 Python 读取模式下方的 5 行,并在读取第一个空行时停止

这是我的脚本:

#!usr/bin/env python

import re

pattern = r'PATTERN:'+'$'

count = 0
fp = open('fileinput.txt')
for line in fp:
    count += 1

    match = re.search(pattern,line)
    if match:
        print 'Matched text:', line, 'Line', count
        line_match = count   

new_line = line_match+4

我已经标记了我想要的行,但无法告诉 Python 从此时开始读取文件,并在遇到空行时退出。有什么建议吗?

【问题讨论】:

  • nt 变量在那里没用。
  • 在提取您想要的数据之前,您是否必须阅读整个文件?似乎解决方案可能是在line_match = countbreak 之后立即跳出循环。
  • @ChrisP 我需要至少读取整个文件一次才能匹配正则表达式,对吧?一旦我得到一个匹配,我想去下面的 5 行并继续阅读直到 NEXT 空行。所以在这种情况下,我应该得到STARTEND之间的文本
  • 为什么不从击球开始算起?

标签: python regex string file


【解决方案1】:

我认为你根本不需要正则表达式,你可以使用endswith。这是我将如何实现它。它不可扩展,但它可以满足您的需求:

matching = False
found = []
with open('fileinput.txt', 'r') as file
    it = iter(file)
    for line in it:
        if matching:
            if line.strip() == '':
                break
            else:
                found.append(line)
        elif line.endswith('PATTERN:'):
            for _ in range(6):
                next(it)
            matching = True

既然您知道START 出现在PATTERN 之后的5 行,因此无需搜索它,因此我使用assert 来确保它在预期的位置。匹配的行存储到found,你可以用

很好地打印出来
for line in found:
    print line

【讨论】:

  • 如果我每次都有STARTEND,这种方法就很棒。我实际上在我的实际数据中的这些位置有随机浮点数。我只是在这个例子中使用了STARTEND 来简化我的问题。我只想匹配 PATTERN 并直接查看下面的 5 行,而不执行任何检查。然后,从START 行开始,我想继续阅读,直到遇到END 下面的空行。
  • 有没有办法使用for line in file 并要求Python 从特定行开始读取?我可以轻松使用readlines()[startline:endline],但是当我遇到空行时,我无法指定break。这就是我卡住的地方
  • 没有意识到 START 和 END 只是占位符 - 我已经更新了答案,所以它现在应该可以工作了。但是,您搜索PATTERN,python 至少需要读取该文件,因此您不会通过尝试告诉它从哪里开始来真正获得任何东西。
  • 非常感谢,成功了!不过只有两件事:1. 真的有必要使用with open(filename) as file 对象方法吗?我以前从未使用过它,也不知道它是如何工作的 2. 我和周围很多 Python 新手一起工作,那么如何确保我的代码可读、干净并且可以自定义?
  • 逻辑很简单。我想我可以用 cmets 来描述 withiter 语句的作用
【解决方案2】:

我没有很好地理解你的解释;据我所知,您需要:

1) 从特定模式读取文件直到空行;
2) 将读取的部分与多行模式匹配。

要实现这一点:

1) 使用 readline()readlines()xreadlines()for line in file 将所有感兴趣的文本读入单个变量中 - 最方便的方法。
请注意,for line if file 循环可以随时用break 停止,xreadlines() - 只是停止读取。下次调用它们时,它们将从文件中的当前位置开始。
2) 将其与包含\n's 的模式匹配或使用re.M 标志如果您需要. 来匹配换行符。

for l in f:
    if re.match("PATTERN:\n",l): break
s=""
for l in f:
    if l=='\n': break
    s+=l
m=re.match("<whatever-pattern-matches-your-chunk-of-text>",s)

【讨论】:

  • 我不知道for line in file 方法在下次调用时会从同一行继续。那太棒了。有没有办法直接开始读取文件下面的 5 行,而不必指定新的正则表达式?
  • for i in range(5): s+=f.readline()f 中的当前位置准确地将 5 行读入s。如果您需要跳过 5 行,只需阅读它们,无需将结果保存在任何地方。 (想一想:您必须读取数据以查看第 5 行结尾的位置,不是吗?;)
  • 由于某种原因,您上面显示的 for 循环不起作用。我收到以下错误:ValueError: Mixing iteration and read methods would lose data 是否与更高版本的 Python 有关?我正在使用 v2.7
  • 啊,是的。 xreadlines()/for l in f 做一些内部缓存,所以f.tell() 不一定只是超过你得到的文本(尽管迭代器的行为就像它一样)。猜猜你必须调用f.xreadlines().next()iter(f).next()(相同)而不是f.readline(),因为你开始使用迭代器。内部缓存在所有文件的迭代器之间共享(事实上,它们都是同一个对象;))所以不用担心丢失任何东西。
猜你喜欢
  • 2016-07-25
  • 1970-01-01
  • 1970-01-01
  • 2018-04-06
  • 1970-01-01
  • 2020-01-29
  • 2018-04-21
  • 1970-01-01
  • 2015-04-30
相关资源
最近更新 更多