Как вернуть строку, если re.findall не находит совпадений - PullRequest
0 голосов
/ 02 июля 2019

Я пишу сценарий, чтобы взять отсканированные файлы 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))

Ответы [ 4 ]

1 голос
/ 02 июля 2019

re.findall возвращает пустой список при отсутствии совпадений.Так что это должно быть так просто:

result = re.findall(my_pattern, my_text)
if result:
    # Successful logic here
else:
    return "Error"
1 голос
/ 02 июля 2019

При таком подходе for match in re.findall(pattern,extracted_string):
если re.findall(...) не найдет совпадений - цикл for не будет даже работать.

Заранее сохраните результат сопоставления в переменную, затем - проверьте с условием:

...
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: не будет иметь смысла, так как каждый подобранный элемент в любом случае является строкой (в противном случае более сложный анализ содержимого строки мог бы быть подразумеваемый).

0 голосов
/ 02 июля 2019

Вы можете сделать это в одной строке:

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

Кстати, вы не получаете никакой выгоды от компиляции шаблона в цикле вендора, потому что вы используете его только один раз.

Ваша функция также может вернуть весь результат поиска, используя единый список:

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

Немного странно, что вы на самом деле хотите изменить И вернуть список результатов, переданный в качестве параметра. Это может привести к неожиданным побочным эффектам при использовании функции.

Ваш флаг «Ошибка» может появляться несколько раз в списке результатов, и, учитывая, что каждый шаблон может возвращать несколько совпадений, будет трудно определить, какой шаблон не смог найти значение.

Если вы хотите сообщить об ошибке только в том случае, если ни один из шаблонов поставщиков не соответствует, вы можете использовать трюк or ["Error"] для всего результата:

return [m for v in vendor for m in re.findall(v, extracted_string)] or ["Error"]
0 голосов
/ 02 июля 2019

У вас есть

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.

Вам необходимо проверить match is None вне цикла for.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...