Extraer partes de texto entre delimitadores específicos de un archivo de texto grande con delimitadores personalizados y escribirlo en otro archivo usando Python

Estoy trabajando en un proyecto que implica crear una base de datos del código federal de los EE. UU. En un formato determinado. He obtenido el código completo de la fuente oficial que no está bien estructurado. He logrado raspar el Código de los EE. UU. En el formato de abajo en archivos de texto usando algún código en GITHUB.

-CITE- 13 USC Sec. 1 1/15/2013 -EXPCITE- TITLE 13 - CENSUS CHAPTER 1 - ADMINISTRATION SUBCHAPTER I - GENERAL PROVISIONS -HEAD- Sec. 1. Definitions -STATUTE- As used in this title, unless the context requires another meaning or unless it is otherwise provided - (1) "Bureau" means the Bureau of the Census; (2) "Secretary" means the Secretary of Commerce; and (3) "respondent" includes a corporation, company, association, firm, partnership, proprietorship, society, joint stock company, individual, or other organization or entity which reported information, or on behalf of which information was reported, in response to a questionnair, inquiry, or other request of the Bureau. -SOURCE- (Aug. 31, 1954, ch. 1158, 68 Stat. 1012; Pub. L. 94-521, Sec. 1, Oct. 17, 1976, 90 Stat. 2459.) -MISC1-  -End- -CITE- 13 USC Sec. 2 1/15/2013 -EXPCITE- TITLE 13 - CENSUS CHAPTER 1 - ADMINISTRATION SUBCHAPTER I - GENERAL PROVISIONS -HEAD- Sec. 2. Bureau of the Census -STATUTE- The Bureau is continued as an agency within, and under the jurisdiction of, the Department of Commerce. -SOURCE- (Aug. 31, 1954, ch. 1158, 68 Stat. 1012.) -MISC1-  -End- 

Cada archivo de texto contiene miles de bloques de este tipo que comienzan con una etiqueta -CITE- y terminan con un -END-.

Aparte de estos, hay ciertos bloques que representan el inicio de un capítulo o subcapítulo y estos no contienen una etiqueta -STATUTE-.

P.ej

 -CITE- 13 USC CHAPTER 3 - COLLECTION AND PUBLICATION OF STATISTICS 1/15/2013 -EXPCITE- TITLE 13 - CENSUS CHAPTER 3 - COLLECTION AND PUBLICATION OF STATISTICS -HEAD- CHAPTER 3 - COLLECTION AND PUBLICATION OF STATISTICS -MISC1- SUBCHAPTER I - COTTON Sec. 41. Collection and publication. 42. Contents of reports; number of bales of linter; distribution; publication by Department of Agriculture. 43. Records and reports of cotton ginners. SUBCHAPTER II - OILSEEDS, NUTS, AND KERNELS; FATS, OILS, AND GREASES 61. Collection and publication. 62. Additional statistics. 63. Duplicate collection of statistics prohibited; access to available statistics. SUBCHAPTER III - APPAREL AND TEXTILES 81. Statistics on apparel and textile industries. SUBCHAPTER IV - QUARTERLY FINANCIAL STATISTICS 91. Collection and publication. SUBCHAPTER V - MISCELLANEOUS 101. Defective, dependent, and delinquent classes; crime. 102. Religion. 103. Designation of reports. AMENDMENTS  -End- 

Solo me interesan aquellos bloques que tienen una etiqueta -STATUTE-.

¿Hay alguna forma de extraer solo los bloques de texto que tienen la etiqueta -STATUTE- y escribirlos en otro archivo de texto?

Soy nuevo en Python, pero me dicen que esto se puede hacer fácilmente en Python.

Aprecio si alguien me puede guiar con esto.

Leí el texto línea por línea y lo analicé yo mismo. De esta manera usted puede manejar grandes entradas como flujos. Existen soluciones más agradables que utilizan expresiones regulares de varias líneas, pero esas siempre sufrirán por no poder manejar la entrada como un flujo.

 #!/usr/bin/env python import sys, re # states for our state machine: OUTSIDE = 0 INSIDE = 1 INSIDE_AFTER_STATUTE = 2 def eachCite(stream): state = OUTSIDE for lineNumber, line in enumerate(stream): if state in (INSIDE, INSIDE_AFTER_STATUTE): capture += line if re.match('^-CITE-', line): if state == OUTSIDE: state = INSIDE capture = line elif state in (INSIDE, INSIDE_AFTER_STATUTE): raise Exception("-CITE- in -CITE-??", lineNumber) else: raise NotImplementedError(state) elif re.match('^-End-', line): if state == OUTSIDE: raise Exception("-End- without -CITE-??", lineNumber) elif state == INSIDE: yield False, capture state = OUTSIDE elif state == INSIDE_AFTER_STATUTE: yield True, capture state = OUTSIDE else: raise NotImplementedError(state) elif re.match('^-STATUTE-', line): if state == OUTSIDE: raise Exception("-STATUTE- without -CITE-??", lineNumber) elif state == INSIDE: state = INSIDE_AFTER_STATUTE elif state == INSIDE_AFTER_STATUTE: raise Exception("-STATUTE- after -STATUTE-??", lineNumber) else: raise NotImplementedError(state) if state != OUTSIDE: raise Exception("EOF in -CITE-??") for withStatute, cite in eachCite(sys.stdin): if withStatute: print "found cite with statute:" print cite 

En caso de que quieras procesar no sys.stdin , puedes hacerlo así:

 with open('myInputFileName') as myInputFile, \ open('myOutputFileName', 'w') as myOutputFile: for withStatute, cite in eachCite(myInputFile): if withStatute: myOutputFile.write("found cite with statute:\n") myOutputFile.write(cite) 

Entonces, para cada línea, si comienza con un guión, seguido de un texto en mayúscula, seguido de otro guión, entonces es un marcador que señala que estamos en una nueva sección de algún tipo. Esto se puede hacer usando una expresión regular:

 current_section_type = None r= re.compile("^-([AZ]*)-") for line in f.readlines(): m=r.match(line) if m: current_section_type = m.group(1) else: if current_section_type == "STATUTE": print line.strip()