un Regex para extraer una oración de un párrafo en python

Estoy tratando de extraer una oración de un párrafo usando expresiones regulares en python.
Normalmente, el código que estoy probando extrae la oración correctamente, pero en el siguiente párrafo la oración no se extrae correctamente.

El párrafo:

“Pero en el caso de las infecciones de malaria y la sepsis, las células dendríticas de todo el cuerpo se concentran en alertar al sistema inmunológico, lo que les impide detectar y responder a nuevas infecciones”. ¿Un nuevo tipo de vacuna?

El código:

def splitParagraphIntoSentences(paragraph): import re sentenceEnders = re.compile('[.!?][\s]{1,2}(?=[AZ])') sentenceList = sentenceEnders.split(paragraph) return sentenceList if __name__ == '__main__': f = open("bs.txt", 'r') text = f.read() mylist = [] sentences = splitParagraphIntoSentences(text) for s in sentences: mylist.append(s.strip()) for i in mylist: print i 

Cuando se prueba con el párrafo anterior, da salida exactamente como el párrafo de entrada, pero la salida debería ser similar a:

    Pero en el caso de las infecciones de malaria y la sepsis, las células dendríticas de todo el cuerpo se concentran en alertar al sistema inmunológico, lo que les impide detectar y responder a nuevas infecciones.

    Un nuevo tipo de vacuna.

    ¿Hay algo malo con la expresión regular?

    El párrafo que ha publicado como ejemplo tiene su primera oración encerrada entre comillas dobles " , y la cita de cierre viene inmediatamente después de la parada completa: infecciones”.

    Su expresión regular [.!?]\s{1,2} está buscando un período seguido de uno o dos espacios como terminador de la oración, por lo que no lo detectará.

    Puede ajustarse para hacer frente a este caso permitiendo citas de cierre opcionales:

     sentenceEnders = re.compile(r'''[.!?]['"]?\s{1,2}(?=[AZ])''') 

    Sin embargo, con la expresión regular anterior, estaría eliminando la cita final de la oración. Mantenerlo es un poco más complicado y puede hacerse usando una aserción de búsqueda:

     sentenceEnders = re.compile(r'''(?<=[.!?]['"\s])\s*(?=[AZ])''') 

    Tenga en cuenta, sin embargo, que hay muchos casos en los que falla un divisor basado en expresiones regulares, por ejemplo:

    • Abreviaturas: "En los trabajos del Dr. AB Givental ..." - según su expresión regular , esto se dividirá incorrectamente después de "Dr." , "A". y "B". (Puede ajustar el caso de una sola letra, pero no puede detectar una abreviatura a menos que la codifique).

    • Uso de signos de exclamación en la mitad de la frase: "... cuando, he aquí que apareció el propio Deshayes ..."

    • Uso de múltiples comillas y citas anidadas, etc.

    La respuesta de Riccardo Murri es correcta, pero pensé que iba a aclarar un poco más el tema.

    Se hizo una pregunta similar con respecto a PHP: detección de límites de oraciones de PHP . Mi respuesta a esa pregunta incluye el manejo de las excepciones como “Sr.”, “Sra.” y “Jr.”. He adaptado esa expresión regular para trabajar con Python, (que impone más restricciones a las miradas). Aquí hay una versión modificada y probada de su script que usa esta nueva expresión regular:

     def splitParagraphIntoSentences(paragraph): import re sentenceEnders = re.compile(r""" # Split sentences on whitespace between them. (?: # Group for two positive lookbehinds. (?<=[.!?]) # Either an end of sentence punct, | (?<=[.!?]['"]) # or end of sentence punct and quote. ) # End group of two positive lookbehinds. (? 

    Puede ver cómo maneja los casos especiales y es fácil agregarlos o eliminarlos según sea necesario. Analiza correctamente su párrafo de ejemplo. También analiza correctamente el siguiente párrafo de prueba (que incluye más casos especiales):

    Esta es la primera frase. Oración dos! Oración tres? Oración "cuatro". Oración "cinco"! Oración "seis"? Oración "siete". Oración '¡ocho!' El Dr. Jones dijo: "¡Sra. Smith, tiene una hija encantadora!"

    Pero tenga en cuenta que hay otras excepciones que pueden fallar y que Riccardo Murri ha señalado correctamente.

    Sí, hay algo mal. Solo tiene en cuenta el separador si va seguido de uno o dos espacios y luego una letra mayúscula, por lo que al final de “¿Un nuevo tipo de vacuna?” La oración no se emparejará, por ejemplo.

    Tampoco sería demasiado restrictivo con respecto a los espacios, a menos que sea una intención (el texto podría no estar bien formado), porque, por ejemplo, “¡Hola, Lucky Boy! ¿Cómo estás hoy?” no se dividiría

    Tampoco entiendo su ejemplo, ¿por qué solo se incluye la primera oración en “?

    De todas formas:

     >>> Text="""But in the case of malaria infections, dendritic cells and stuff. A new type of vaccine? My uncle! """ >>> Sentences = re.split('[?!.][\s]*',Text) >>> Sentences ['But in the case of malaria infections, dendritic cells and stuff', 'A new type of vaccine', 'My uncle', ''] 

    También puede filtrar las oraciones vacías:

     >>> NonemptyS = [ s for s in Senteces if s ]