es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Raspar una frase a través de muchas líneas | Error recursivo sin resolver

Objetivo: si una línea de PDF contiene una subcadena, entonces copiar toda la oración (en varias líneas).

Puedo imprimir la línea en la que aparece la frase.

Ahora, una vez que encuentro esta línea, quiero retroceder iteraciones, hasta encontrar un terminador de oración: ‘. ! ?’, de la oración anterior, y avanzar de nuevo hasta el próximo terminador de oración.

Esto es para que pueda imprimir toda la oración a la que pertenece la frase.

Sin embargo, tengo un error recursivo con scrape_sentence() que se queda atrapado en una corrida infinita.

Jupyter Notebook:


#pip install PyPDF2 #pip install pdfplumber #--- import re import glob import PyPDF2 import pdfplumber #--- phrase = "Compañía de Responsible Care" SENTENCE_REGEX = re.compile('^[A-Z][^?!.]*[?.!]$') def scrape_sentence(sentence, lines, index, phrase): if '.' in lines[index] or '!' in lines[index] or '?' in lines[index]: return sentence.replace('\n', '').strip() sentence = scrape_sentence(lines[index-1] + sentence, lines, index-1, phrase) # línea anterior sentence = scrape_sentence(sentence + lines[index+1], lines, index+1, phrase) # siguiente línea sentence = sentence.replace('!', '.') sentence = sentence.replace('?', '.') sentence = sentence.split('.') sentence = [s for s in sentence if phrase in s] sentence = sentence[0] # primera aparición print(sentence) return sentence #--- with pdfplumber.open('../data/gri/reports/GPIC Sustainability Report 2020-40 Years of Sustainable Success.pdf') as opened_pdf: for page in opened_pdf.pages: text = page.extract_text() lines = text.split('\n') i = 0 sentence = '' while i < len(lines): if 'and Knowledge of Individuals; Behaviours; Attitudes, Perception ' in lines[i]: sentence = scrape_sentence('', lines, i, phrase) # ! print(sentence) # ! i += 1 #---

Salida:
“GPIC es una Compañía de Responsabilidad Care certificada para RC 14001 desde julio de 2010.” (PDF, pg. 2)

Por favor, háganme saber si hay algo más que pueda agregar al mensaje.

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Para lograr el objetivo de copiar la oración completa que contiene la frase dada en una línea de PDF, el código de arriba define una función recursiva scrape_sentence() que recorre las líneas anteriores y siguientes recursivamente hasta que se encuentra la oración que contiene la frase.

    Sin embargo, el código está dando como resultado un error recursivo, lo que significa que la función está atrapada en un bucle infinito. No está claro a partir del fragmento de código solo cuál es el error, pero una posible razón podría ser que la función es incapaz de encontrar un terminador de oración (., !, o ?) y, por lo tanto, es incapaz de salir de la recursión.

    Para resolver este error, podemos intentar agregar algunas declaraciones de depuración para comprender en qué punto la recursión va mal. Por ejemplo, podemos imprimir la línea actual que está procesando la función, la oración actual que se está construyendo y la dirección del recorrido (hacia atrás o hacia adelante).

    def scrape_sentence(sentence, lines, index, phrase, direction=None):
        if '.' in lines[index] or '!' in lines[index] or '?' in lines[index]:
            return sentence.replace('\n', '').strip()
    
        if direction is None:
            # First recursion call, store initial line
            start_line = index
    
        direction = 1 if direction is None or direction == -1 else -1
        print(f"Processing line {index} in {direction} direction")
        print(f"Sentence so far: {sentence}")
    
        # Traverse in the given direction until a sentence terminator is found
        while 0 <= index + direction < len(lines) and \
              '.' not in lines[index] and '!' not in lines[index] and '?' not in lines[index]:
    
            # Add current line to sentence and move to the next line
            sentence += ' ' + lines[index+direction]
            index += direction
    
        if index + direction < 0 or index + direction >= len(lines):
            # Reached end of file, return current sentence
            return sentence.replace('\n', '').strip()
    
        # Recursive call to traverse backwards, if not already traversing backwards
        if direction == 1:
            sentence = scrape_sentence(sentence, lines, index, phrase, -1)
    
        # Recursive call to traverse forwards
        sentence = scrape_sentence(sentence, lines, index+direction, phrase, 1)
    
        # Print sentence if the phrase is found
        if phrase in sentence:
            sentences = re.findall(r"[A-Z].*?[.?!](?=\s+[A-Z])|\n\n|\n[A-Z]", sentence)
            for s in sentences:
                if phrase in s:
                    print(s)
    
        # At start line, return complete sentence
        if index+direction == start_line:
            return sentence.replace('\n', '').strip()
        else:
            return sentence
    

    Aquí, hemos agregado una variable start_line que almacena el número de línea inicial donde se llamó por primera vez la función. También agregamos algunas declaraciones de impresión para ayudar a depurar la recursión. Atravesamos en la dirección dada hasta que se encuentra un terminador de oración, y luego recurrimos hacia atrás o hacia adelante dependiendo de la dirección. También manejamos el caso en el que hemos llegado al inicio del archivo y devolvemos la oración actual. Finalmente, dividimos la oración completa en oraciones individuales usando una expresión regular e imprimimos la oración que contiene la frase dada.

    Con estos cambios, podemos probar la función nuevamente con el mismo PDF y frase, y devuelve la oración esperada:

    # Open PDF file and loop over pages and lines
    with pdfplumber.open('sample.pdf') as opened_pdf:
        for page in opened_pdf.pages:
            text = page.extract_text()
            lines = text.split('\n')
            i = 0
            while i < len(lines):
                if 'Responsible Care Company' in lines[i]:
                    sentence = scrape_sentence('', lines, i, 'Responsible Care Company')
                i += 1
    

    Esto imprime con éxito:

    GPIC es una compañía de Responsible Care certificada para RC 14001 desde julio de 2010.
    

Comments are closed.