【问题标题】:With a dictionary, search for strings in another text file and print the entire line使用字典,在另一个文本文件中搜索字符串并打印整行
【发布时间】:2014-10-30 00:46:52
【问题描述】:

我想从字典中搜索其中一个单词是否在第二个 txt 文件中。 我对以下代码有疑问:

print 'Searching for known strings...\n'
with open('something.txt') as f:
    haystack = f.read()
with open('d:\\Users\\something\\Desktop\\something\\dictionary\\entirelist.txt') as f:
    for needle in (line.strip() for line in f):
        if needle in haystack:
            print line

with open 语句不是来自我,我是从: Search for strings listed in one file from another text file? 我想打印这条线,所以我写的是线而不是针。问题来了:上面写着line is not defined

我的最终目标是查看字典中是否有任何单词在“something.txt”中,如果是,则打印识别出该单词的行。

【问题讨论】:

  • 您能给我们举个例子(简化为 3 行)something.txtentirelist.txt 的样子,以及您想要的输出吗?

标签: python


【解决方案1】:

您询问的具体例外是因为line 在生成器表达式之外不存在。如果要访问它,则需要将其保持在与print 语句相同的范围内,如下所示:

for line in f:
    needle = line.strip()
    if needle in haystack:
        print line

但这不会特别有用。它只是来自needle 的单词加上末尾的换行符。如果您想从haystack 中打印出包含needle 的行(或行?),您必须搜索该行,而不仅仅是询问needle 是否出现在整个haystack 中的任何位置。

要真正按照您的要求进行操作,您需要遍历haystack 的行并检查每一行是否有needle。像这样:

with open('something.txt') as f:
    haystacks = list(f)

with open('d:\\Users\\something\\Desktop\\something\\dictionary\\entirelist.txt') as f:
    for line in f:
        needle = line.strip()
        for haystack in haystacks:
            if needle in haystack:
                print haystack

但是,您可能需要考虑一个巧妙的技巧:如果您可以编写一个匹配包含needle 的任何完整行的正则表达式,那么您只需打印出所有匹配项。像这样:

with open('something.txt') as f:
    haystack = f.read()
with open('d:\\Users\\something\\Desktop\\something\\dictionary\\entirelist.txt') as f:
    for line in f:
        needle = line.strip()
        pattern = '^.*{}.*$'.format(re.escape(needle))
        for match in re.finditer(pattern, haystack, re.MULTILINE):
            print match.group(0)

以下是正则表达式如何工作的示例:

^.*Falco.*$

Debuggex Demo

当然,如果你想不区分大小写搜索,或者只搜索完整的单词等,你需要做一些小的改动;有关更多信息,请参阅Regular Expression HOWTO 或第三方教程。

【讨论】:

  • 你的第二个效果很好,第三个打印出类似:<_sre.sre_match object at> 另外我对不区分大小写和完整单词的搜索感兴趣,所以我会看看你的链接,单独尝试,看看会发生什么:) 感谢您的帮助 + 提供替代方案 :)
  • @Maxim:对,对不起,finditer 返回MatchObjects,而不仅仅是匹配的字符串。这更有用,但如果你想看看发生了什么……好吧,我已经编辑了答案。要使正则表达式不区分大小写,您只需添加另一个标志 (re.MULTILINE | re.IGNORECASE)。只匹配完整的单词,如果你很幸运并且\b 有你想要的相同的单词定义,那很容易;否则它会涉及更多。无论如何,一定要使用 Debuggex 或其他正则表达式工具来玩东西,这比通常的源代码编辑-调试周期要容易得多。
  • 再次感谢您!如何匹配具有相同定义的完整单词?另外我想检查该行的 str 是否已经打印,如果是,则不打印。可能吗?
  • 我补充说:needle = ' ' + needle 它似乎适用于“半完整单词”。 (否则,如果我写了needle = ' ' + needle + ' ',它不会计算第一个(不是问题)和最后一个(这是一个问题)单词。)
  • @Maxim:了解\b 的作用。假设一个单词的正则表达式定义足够接近,\bFalco\b 而不仅仅是Falco 将匹配So says Falco.That's Falco's third album 中的Falco,但不匹配The Falcon and the Snowman
【解决方案2】:

看起来你使用了一个生成器:(line.strip() for line in f),我认为你不能从生成器范围之外访问内部变量“line”,即在括号之外.

尝试类似:

for line in f:
    if line.strip() in haystack:
        print line

【讨论】:

  • 因为line.strip() 只是一个字符串(字典中的一行,已删除换行符),所以您的for needle in line.strip(): 将是该行中的每个字符。所以这不可能是对的。
猜你喜欢
  • 1970-01-01
  • 2011-11-26
  • 2017-05-23
  • 2016-10-20
  • 2015-09-11
  • 1970-01-01
  • 2014-09-06
  • 2014-02-13
  • 2017-11-17
相关资源
最近更新 更多