2016-06-09 17 views
1

(Verwendung Python 2,7)Extrahieren von Text zwischen den Ziffern - Python

einen Vertrag vor, das unter anderem Text, Textblocks von Abschnittsnummern hat, getrennt. Ich versuche, den Text jedes Abschnitts zu extrahieren und in ein neues Dokument zu schreiben. Wenn also ein Vertrag mit zweihundert Seiten dreißig Abschnitte hat, die durch Abschnittsnummern getrennt sind, möchte ich diese dreißig Abschnitte in einem neuen Dokument haben.

Ich schaute auf diese Antwort Extracting parts of text between specific delimiters from a large text file with custom delimiters and writing it to another file using Python, aber es schien nicht zu tun, was ich tun möchte.

Ein Beispiel dafür, was ich versuche, den Text zwischen den nummerierten Abschnitten (ein großer Bonus wäre, den Abschnittskopf neben dem nummerierten Abschnitt) zu extrahieren wäre, d.h .:

1.2.3.4. Ein Abschnitt

Einige Text. Ein anderer Text auch. Und Zeug. Und noch mehr Text in der nächsten Zeile.

1.2.3.5. Der nächste Abschnitt

So viel mehr Text, mit Kommas und Zeug. Sogar Zeilenumbrüche und was nicht.

1.2.3.6. Einige Abschnitte sind wirklich toll

Willkommen in diesem Abschnitt. Was wahrscheinlich besser ist als andere. Und ich kann nicht einmal anfangen zu erklären, wie großartig es ist.

1.2.3.7. Was? Ein neuer Abschnitt?

Dang richtig, es ist ein neuer Abschnitt! Bist du nicht bereit dafür? So viele neue Abschnitte können für Text verwendet werden, den Sie nie lesen werden.

Im Idealfall werde ich in einer einzigen Datei lesen und eine einzige Datei ausgeben. Bisher habe ich Variationen des Codes vergeblich versucht. Ich weiß, dass dies fehlt der Schreibe-zu-Ausgabe-Teil (noch nicht dort angekommen):

import codecs 
import re 

regex = r'\D(?!\d)' 

# read a contract in 
with codecs.open("/Users/someuser/x/y/blah.txt", "r","utf-8") as ins: 
    text = ins.read() 

# perform magics 
output = re.findall(regex, text) 

output 
+0

kann nicht nur die Datei Zeile für Zeile lesen, und wenn die Zeile beginnt mit 'r (\ d \.) [4]' Sie das Stück Text mit einem leeren String ersetzen und mach weiter? –

+0

@MauriceReeves Die Verträge haben also viele andere Texte, die nicht durch nummerierte Abschnitte eingeklammert sind. Denken Sie an so etwas wie einen Mietvertrag ... Sie haben viel Text, der das Arrangement, Partys usw. beschreibt, aber auch eine sehr spezifische, nummerierte Sektionssprache (ich möchte nur das Letztere). Ich denke, wenn ich die Ersatz-Option nehme, die Sie beschreiben, würde ich mit jedem Text im Dokument enden, was ich nicht anstrebe. – nacc

+0

Okay, gut genug, aber nachdem du den Abschnitt mit der letzten Nummer getroffen hast, wirst du trotzdem alles bekommen, was danach folgt. Sie könnten besser zwei Durchgänge auf dem Dokument machen. –

Antwort

1

Ok, wenn ich also richtig verstehe, wollen Sie alles zwischen den Abschnittsnummern erfassen.

Hier ist die Regex Zeichenfolge kam ich mit: regex = r'(?:\d\.){4}.(.+?)(?:\d\.){4}'

Lass sie, dass bricht ein wenig nach unten:

(?:\d\.){4} das ist unsere 4 Zahlen gefolgt von einem Punkt. Die (?:) macht es zu einer nicht einfangenden Gruppe, also können wir nach diesem Muster suchen, um es 4 mal zu zählen, aber nicht zu unseren Matches hinzuzufügen.

(.+?) Dies ist der Teil, den wir erfassen möchten. Wenn Klammern ohne ?: verwendet werden, wird eine Erfassungsgruppe erstellt. .+? bedeutet eines oder mehrere beliebiger Zeichen, nicht gierig. Das Fragezeichen ist der nicht-gierige Teil, und es bedeutet, dass wir die Zeichen nicht für immer behalten, wir hören auf, wenn wir zum nächsten Teil des Ausdrucks kommen.

(?:\d\.){4} Wir mit unserem Abschnitt Muster wieder beenden, weil wir zwischen zwei Abschnitten

Hier erfassen wollen, ist der Code, den wir verwenden, zu packen, was wir wollen:

p = re.compile(regex, flags=re.DOTALL)

Die DOTALL Flagge erlaubt Um Zeilenumbrüche zu erhalten, passt . normalerweise zu allen Zeichen außer newline.

sections = p.findall(text) wo Text Zeichenfolge ist durch

Die findall Methode liefert eine Liste der zwischengespeicherten Gruppen suchen wir abgestimmt.

['A section\n\nSome text. Some other text, too. And stuff. And even more text on the next line.\n\n', "Some sections are really great\n\nWelcome to this section. Which is probably better than others. And I can't even begin to explain how great it is.\n\n"]

+0

Es sieht aus wie in Ihrem Fall Ihre Lösung den letzten Abschnitt ablegt: "1.2.3.7. Was? Ein neuer Abschnitt? Dang richtig, es ist ein neuer Abschnitt! Sind Sie nicht sogar bereit dafür? So viele neue Abschnitte können verwendet werden für Text, den du nie lesen wirst. " Es scheint, als ob er nur Dinge haben will, die Sektions-Header haben, und er will, dass sie entfernt werden. Leider sieht es nicht so aus, als ob ein Abschnitt Header und was nicht ist in den Dokumenten nicht gut definiert ist. –

+0

Oh ja, daran habe ich nicht gedacht. – sajattack

+0

Ich bat ihn um mehr Details, nur um zu sehen, ob wir zu einer besseren Lösung kommen konnten, aber noch nicht gehört haben. Deine Lösung ist sehr nah, solange wir herausfinden können, was das nächste Stück nach diesem bestimmten Abschnitt ist. Vielleicht gibt es eine saubere Pause, und mit einer kleinen Änderung wäre Ihre Lösung abgeschlossen. –

1

Würde das nicht nur funktionieren?

Verwandte Themen