cómo usar expresiones regulares para extraer bloques de texto sin separar los bloques de texto en líneas

Quiero extraer el capítulo de un libro usando python. He etiquetado cada capítulo de libro indicando el comienzo y el final de cada capítulo. La etiqueta para el inicio del capítulo es [@introS] y la etiqueta para el final del capítulo es [@ introEnd @]. El objective de mi código es extraer todo lo que se encuentra entre las tags (que corresponden al texto de cada capítulo) y pedir al usuario que nombre cada capítulo y escriba en un archivo. Sin embargo, cuando imprimo el resultado de mi coincidencia, se imprime todo el texto. Este código solo funciona si la etiqueta inicial y la etiqueta final están separadas por líneas.

ejemplo de entrada:

Par suite des contes pseudonymes no aparece en vient de parler, feu M. John Ballantyne, éditeur $ des ouvrages de Walter Scott, una sesión de discusión con su hermano de Londres, chacun $ d’eux soutenant y son Jedediah Cleishbotham était le vrai en Simon City . $ CHAPITRE PREMIER. $ [@ introS] C’est aux moines qu’on doit la superstition, $ La nuit des préjugés et des erreurs grossières $ Qui couvrit si longtemps les siècles of nos pères. $ – Je bénis comme vous la bienfaisante main $ Qui de tous ces fléaux purgea le genre humain: $ Mais sur les moines seuls en rejeter la cause, $ C’est à quoi ma raison trop fortement s’oppose. $ Je croirais aussi bien que Molly Warburton, $ Traversant cette nuit les airs sur a bâton, $ Causa l’orage affreux qui gronda sur nos têtes. $ Ancienne comédie. $ E village auquel le manuscrit du bénédictin donne le nom $ de Kennaquhair porte la même terminación celtique qu’on $ trouve dans Traquhair, Caquhair, et d’autres mots com $ posés. Le savant Chalmers se refiere a la syntax de la ciudad, y al nombre de la familia de Tweed en el pueblo de Twittea, en el pueblo de la especie $ assez vraisemblable [@ introEnd @]. [@IntroS] Longtemps Kennaquhair a été céièbre par le $ superbe monastère de Sainte-Marie, fondé par David I “, roi d’Écosse, $ sous le règne duquel s’élevèrent aussi les couvents non moins riches $ de Melrose, de Jedburgh et de Kelso. Les domaines considérables $ que ce monarque accorda à ces divers établissements religieux lui $ firent décerner le titre de saint par les moines qui écrivirent les chro $ niques de ce temps, et dire par a ses descendant appauvris, – qu’il avait été un triste saint pour la couronne. ‘En el caso de David, Prince Aussisage Que Pieux, $ ne fut pas déterminé seulement par des motifs of religion à ces grandds $ • _ / $ [@ introEnd @]. [@introS] Google est fier de travailler en partenariat avec des bibliothËques ‡ the numberÈrisation des ouvrages appartenant au domaine public et de les rendre $ ainsi accessibles ‡ tous. Ces livres sont en effet the propriÈtÈ de tous et de toutes et nous sommes tout simplement les gardiens de ce patrimoine. $ Il s’agit toutefois d’un projet co˚teux. Consistente y en vue de la búsqueda de la difusión de recursos de recursos disponibles, nous avons pris les $ disposions n dispositcessairs afin de prenvenir les Èventuels abus auxquels pourra contr el par un parício parásito parásito antipersonal antárquico de los antepasados ​​en este último caso. @].

El código que he probado está abajo.

He intentado usar coincidencias, pero no estoy seguro de que este sea el mejor método … ¿Tal vez intente buscar o buscar?

import re def separate_chapters (): pat = re.compile('(?<=\[@introS\]).+?(?=\[@introEnd@\])') with open('text1_scott.txt') as file: for i in filter(pat.match, file): print(i) inp = input("write text to a file? Y|N: ") if inp != "Y": continue file_name = input("Name of your file: ") with open(file_name, "w") as out_file: out_file.write(i) print("text {} written to a file".format(i)) separate_chapters() 

No quiero separar los capítulos en líneas diferentes para hacer eso … Quiero extraer todo el bloque de texto, incluso si hay tags en la misma línea … ¿Cómo hacerlo?

Tu patrón es un poco incorrecto. Debe escapar [ y ] y no necesita escapar @ ya que @ no es un carácter especial en la expresión regular. También para capturar el contenido entre esas tags de inicio y fin,. no es suficiente, ya que solo capturará un solo personaje, por lo tanto, debe usar la función de mirar alrededor y usar .+? Para capturar texto entre ellos de manera no codiciosa. Trate de usar esta expresión regular,

 (?<=\[@introS\]).+?(?=\[@introEnd@\]) 

Aquí, (?<=\[@introS\]) la vista positiva detrás garantiza que cualquier texto que se [@introS] será precedido por texto literalmente [@introS] y luego .+? captura uno o más de los caracteres lo menos posible y (?=\[@introEnd@\]) la mirada hacia adelante asegura que todo lo que se [@introEnd@] sea ​​seguido literalmente por [@introEnd@]

Demo en linea

Editar:

Hubo varios problemas en su código.

  • Su statement de expresiones regulares no fue correcta, ya que la cadena no fue citada, lo cual ya le dije y usted reparó.
  • Debe llamar a la función read() en file objeto de file para recuperar la cadena del archivo
  • Simplemente puede usar findall simple en lugar de la coincidencia, donde la coincidencia funciona de manera diferente e intenta hacer coincidir el texto completo con expresiones regulares
  • Necesitabas usar encoding="utf-8" para leer / escribir el archivo ya que el archivo contiene caracteres Unicode.

Aquí hay una copia actualizada de su código,

 import re def separate_chapters(): pat = re.compile(r'(?<=\[@introS\]).+?(?=\[@introEnd@\])') with open('text1_scott.txt', 'r', encoding="utf-8") as file: for i in pat.findall(file.read()): print(i) inp = input("write text to a file? Y|N: ") if inp != "Y": continue file_name = input("Name of your file: ") with open(file_name, "w", encoding="utf-8") as out_file: out_file.write(i) print("text {} written to a file".format(i)) separate_chapters() 

Que se ejecutó bien y escribió el texto del capítulo en el nombre de archivo que ingresé cuando se me solicitó el nombre de archivo. Es casi a las 3:00 de la madrugada aquí y me siento demasiado cansado y me voy a dormir, por lo que es posible que no pueda responder a ninguna otra pregunta ahora, pero seguramente lo haré en la mañana. Y ojalá no tengas que enfrentar ningún problema más.