当 re.findall 没有找到匹配项时如何返回一个字符串

3
我正在编写一个脚本,以将扫描的PDF文件转换为文本行并输入到数据库中。我使用re.findall从正则表达式列表中获取匹配项,以从tesseract提取的字符串中获取特定值。当正则表达式找不到我要匹配的内容时,我想让它返回“错误”信息,以便我能够看到问题所在。我尝试了几种if/else语句,但是似乎无法注意到None值。
from wand.image import Image as Img
import ghostscript
from PIL import Image
import pytesseract
import re
import os

def get_text_from_pdf(pendingpdf,pendingimg):
    with Img(filename=pendingpdf, resolution=300) as img:
        img.compression_quality = 99
        img.save(filename=pendingimg)
    pytesseract.pytesseract.tesseract_cmd = r'C:\Program Files\Tesseract-OCR\tesseract'
    extractedtext = pytesseract.image_to_string(Image.open(pendingimg))
    os.unlink(pendingimg)
    return extractedtext

def get_results(vendor,extracted_string,results):
    for v in vendor:
        pattern = re.compile(v)
        for match in re.findall(pattern,extracted_string):
            if type(match) is str:
                results.append(match)
            else:
                results.append("Error")
    return results

pendingpdf = r'J:\TBHscan07022019090315001.pdf'
pendingimg = 'Test1.jpg'
aggind = ["^(\w+)(?:.+)\n+3600",
          "Ticket: (nonsensewordstothrowerror)",
          "Ticket: \d+\s([0-9|/]+)",
          "Product: (\w+.+)\n",
          "Quantity: ([\d\.]+)",
          "Truck (\w+)"]
vendor = aggind
extracted_string = get_text_from_pdf(pendingpdf,pendingimg)
results = []

print(get_results(vendor,get_text_from_pdf(pendingpdf,pendingimg),results))

我得回去看一下,但是不是只有返回匹配项吗? - ThatCampbellKid
你尝试过使用 try except 块吗? - saha rudra
@saharudra 是正确的。这比 if else 更符合 Python 的风格,但 OP 仍然需要知道何时抛出异常。 - Lucas Wieloch
一个 try except 块是不必要的,当没有匹配时,re.findall 不会抛出异常。 - Alex
4个回答

3

您可以在一行代码中完成此操作:

results += re.findall(pattern, extracted_string) or ["Error"]

顺便提一下,如果你只使用一次,那么在vendor循环内编译模式是没有好处的。

您的函数也可以使用单个列表推导式返回整个搜索结果:

return [m for v in vendor for m in re.findall(v, extracted_string) or ["Error"]]

您想修改并返回作为参数传递的结果列表有点奇怪,这可能会在使用函数时产生一些意想不到的副作用。

您的“Error”标志可能会多次出现在结果列表中,并且由于每个模式可能会返回多个匹配项,因此很难确定哪个模式未能找到值。

如果您只想在没有供应商模式匹配时发出错误信号,可以在整个结果上使用or ["Error"]技巧:

return [m for v in vendor for m in re.findall(v, extracted_string)] or ["Error"]

这个非常好用。我基本上是在尝试扫描一堆交货单据并将它们输入到我们的应付账款系统中,这基本上是一个电子表格。无论如何,非常感谢! - Matthew Keith

2
使用这种方法,如果re.findall(...)找不到任何匹配项,则for match in re.findall(pattern,extracted_string):循环将不会运行。
先将匹配结果保存到变量中,然后使用条件进行检查:
...
matches = re.findall(pattern, extracted_string)
if not matches:
    results.append("Error")
else:
    for match in matches:
        results.append(match)

注意,当遍历re.findall(...)的结果时,检查if type(match) is str:没有意义,因为每个匹配项都是一个字符串(否则-可以暗示对字符串内容的更复杂分析)。

1
这个答案比我的更详尽并且是正确的。 - Alex

1

re.findall在没有匹配项时返回一个空列表。因此,只需要简单地使用以下代码:

result = re.findall(my_pattern, my_text)
if result:
    # Successful logic here
else:
    return "Error"

0

你有

for match in re.findall(pattern,extracted_string):
        if type(match) is str:
            results.append(match)
        else:
            results.append("Error")

但是当re.findall()找不到任何内容时,它会返回None,因此

for match in re.findall(pattern,extracted_string):

不会进入,因为匹配是None

你需要在for循环之外检查match is None


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接