【问题标题】:Find all the occurences of a string in an imperfect text在不完美的文本中查找所有出现的字符串
【发布时间】:2017-02-21 10:00:21
【问题描述】:

我试图在从 PDF 文件中提取的长文本中查找一个字符串,并获取该字符串在文本中的位置,然后返回该字符串之前的 100 个单词和之后的 100 个单词。 问题是提取不完美,所以我遇到了这样的问题:

查询字符串是“测试文本”

文本可能如下所示:

这是一个有问题的测试文本

如您所见,单词“test”与字母“a”相连,单词“text”与单词“with”相连

所以唯一与我合作的功能是 __contains __,它不会返回单词的位置。

有什么想法可以在这样的文本中找到一个单词的所有出现及其位置?

非常感谢

【问题讨论】:

  • 这个链接可能有帮助:stackoverflow.com/questions/250271/…
  • 你试过str.find吗?一种常见的模式是重复扫描字符串,每次都从上一次命中开始。顺便说一句,您对该示例的预期输出是什么?字符索引9、单词索引2 或清理后的单词索引3

标签: python


【解决方案1】:

您可以采取以下方法。这首先尝试将整个文本拆分为单词,并记录每个单词的索引。

接下来,它遍历文本以查找 test text,其间可能有 0 个或多个空格。对于每个匹配,它会记录开始,然后使用 Python 的 bisect 库创建在该点之前和之后找到的单词列表,以在 words 列表中找到所需的条目。

import bisect
import re

test = "aa bb cc dd test text ee ff gg testtextwith hh ii jj"

words = [(w.start(), w.group(0)) for w in re.finditer(r'(\b\w+?\b)', test)]

adjacent_words = 2

for match in re.finditer(r'(test\s*?text)', test):
    start, end = match.span()

    words_start = bisect.bisect_left(words, (start, ''))
    words_end = bisect.bisect_right(words, (end, ''))

    words_before = [w for i, w in words[words_start-adjacent_words : words_start]]
    words_after = [w for i, w in words[words_end : words_end + adjacent_words]]

    #  Adjacent words as a list
    print words_before, match.group(0), words_after

    # Or, surrounding text as is.
    print test[words[words_start-adjacent_words][0] : words[words_end+adjacent_words][0]]

    print

所以对于这个有 2 个相邻单词的例子,你会得到以下输出:

['cc', 'dd'] test text ['ee', 'ff']
cc dd test text ee ff 

['ff', 'gg'] testtext ['hh', 'ii']
ff gg testtextwith hh ii

【讨论】:

  • 谢谢!!我从你的回答中学到了很多东西。非常有价值:D
【解决方案2】:

您可以查看regex 模块,它允许“模糊”匹配:

>>> import regex
>>> s='This is atest textwith a problem'
>>> regex.search(r'(?:text with){e<2}', s)
<regex.Match object; span=(14, 22), match='textwith', fuzzy_counts=(0, 0, 1)>
>>> regex.search(r'(?:test text){e<2}', s)
<regex.Match object; span=(8, 18), match='atest text', fuzzy_counts=(0, 1, 0)>

您可以匹配包含插入、删除和错误的文本。返回的匹配组具有跨度和索引。

您可以使用regex.findall 查找所有潜在的目标匹配项。

非常适合您所描述的内容。

【讨论】:

    【解决方案3】:

    您没有指定所有要求,但这适用于您当前的问题。程序打印出9 and 42,这是两次出现test text的开始。

    import re
    filt = re.compile("test text")
    
    for match in filt.finditer('This is atest textwith a problem. another test text'):
        print match.start()
    

    【讨论】:

    • 看来 OP 只在寻找 one 次出现。
    • 标题虽然说“找到所有的出现”?
    • 谢谢这个解决方案非常适合我的问题。非常感谢你^_^
    【解决方案4】:

    如果要查找字符串中文本的位置,可以使用string.find()

    >>> query_string = 'test text'
    >>> text = 'This is atest textwith a problem'
    >>> if query_string in text:
            print text.find(query_string)
    9
    

    【讨论】:

    • find() 返回搜索字符串中第一个实例的索引(最低索引),因此您必须多次迭代搜索文本才能找到所有位置。
    猜你喜欢
    • 1970-01-01
    • 2012-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-23
    相关资源
    最近更新 更多