【问题标题】:selecting the exact match using pymupdf-page.searchFor()使用 pymupdf-page.searchFor() 选择完全匹配
【发布时间】:2020-10-26 11:14:26
【问题描述】:

下面是我的一段代码,我在其中搜索特定单词并提取它们的坐标。

根据文档page.searchFor(), page.searchFor(needle, hit_max=16, quads=False, flags=None). 在页面上搜索 needle。忽略大写/小写。字符串可能包含空格。

首先,我想要精确匹配的坐标。 其次,如果选择的单词是“inter”,它也会从与我的任务冲突的文档中出现的单词 internalization 中提取“inter”的坐标。

有什么方法可以达到同样的效果吗?

doc = fitz.open(document_name)

words = ["Midpoint", "CORPORATE", "internalization"]

for page in doc:
  page._wrapContents()

  for word in words:
      text_instances = page.searchFor(word)

      for rect_coordinates in text_instances:
             page.addRedactAnnot(rect_coordinates, text_color = (0,0,0), fill = (0,0,0))

      page.apply_redactions()

【问题讨论】:

标签: python pymupdf


【解决方案1】:

您可以使用page.getText("words") 获取页面上的文字及其位置。

对我有用的解决方法是使用 page.searchFor() 来获取可能匹配的位置,并基于使用此位置的较大矩形在 getText 中传递剪辑参数。然后,我使用 re 检查了 getText 中的所有单词是否匹配。

但是,您可以使用 page.getText("words") 获取所有单词并迭代所有获得的单词,因为您只需要精确的单词匹配。您也可以传递标志以处理连字符。参考doc link

【讨论】:

    【解决方案2】:

    如果您的搜索词,您可以扩展矩形边界并验证找到的匹配项周围是否有任何相邻文本。

    下面的函数(isExactMatch()) 允许您选择启用ExactMatchCaseSensitive匹配

    def isExactMatch(page, term, clip, fullMatch=False, caseSensitive=False):
    # clip is an item from page.search_for(term, quads=True)
    
        termLen = len(term)
        termBboxLen = max(clip.height, clip.width)
        termfontSize = termBboxLen/termLen
        f = termfontSize*2
    
        clip = clip.rect
    
        validate = page.get_text("blocks", clip = clip + (-f, -f, f, f), flags=0)[0][4]
        flag = 0
        if not caseSensitive:
            flag = re.IGNORECASE
    
        matches = len(re.findall(f'{term}', validate, flags=flag)) > 0
        if fullMatch:
            matches = len(re.findall(f'\\b{term}\\b', validate))>0
        return matches
    
    # how to use isExactMatch function
    
    term = "my_searchterm"
    coordinates = page.search_for(term)
    for inst in coordinates:
        if isExactMatch(page, term, inst, exactMatch=True, matchCase=False):
            print("DoSomething")
    

    请注意,f = termfontSize*2 用于将边界向所有方向扩展 f 个单位f的值是bbox中每个term平均长度的2倍


    更新:2021 年 9 月 22 日:

    请注意,此功能无法正常匹配多行文本,因为剪辑区域未覆盖所有行。

    【讨论】:

    • 请注意,我之前使用的是page.get_textbox,但它返回的是单个单词的数组,这使得检查精确匹配变得困难。所以我切换到page.get_text,它返回一个数组,其中第 5 项 ([4]) 是整个文本作为一个字符串。
    • 我已经在 GitHub Repo 中发起了一个讨论:Exact match using PuMuPDF
    猜你喜欢
    • 1970-01-01
    • 2011-10-04
    • 2023-03-03
    • 1970-01-01
    • 1970-01-01
    • 2022-08-03
    • 2020-12-02
    • 2013-02-28
    • 2021-12-09
    相关资源
    最近更新 更多