2017-06-01 4 views
1

Ich habe Text von pdf extrahiert mit und speicherte das Ergebnis als txt.konvertieren zwei Spalten Textdokument in eine Zeile für Text Mining

Gibt es eine effiziente Möglichkeit, den txt mit 2 Spalten in eine Datei mit einer Spalte zu konvertieren.

Dies ist ein Beispiel dafür, was ich habe:

Alice was beginning to get very  into the book her sister was reading, 
tired of sitting by her sister  but it had no pictures or conversations 
on the bank, and of having nothing in it, `and what is the use of a book,' 
to do: once or twice she had peeped thought Alice `without pictures or conversation?` 

statt

Alice was beginning to get very tired of sitting by her sister on the bank, and 
of having nothing to do: once or twice she had peeped into the book her sister was 
reading, but it had no pictures or conversations in it, `and what is the use of a 
book,' thought Alice `without pictures or conversation?' 

Basierend auf Extract Text from Two-Column PDF with R ich die Funktion ein bisschen zu erhalten geändert:

library(readr)  
trim = function (x) gsub("(?<=[\\s])\\s*|^\\s+|\\s+$", "", x, perl=TRUE) 

QTD_COLUMNS = 2 

read_text = function(text) { 
    result = '' 
    #Get all index of " " from page. 
    lstops = gregexpr(pattern =" ",text) 
    #Puts the index of the most frequents ' ' in a vector. 
    stops = as.integer(names(sort(table(unlist(lstops)),decreasing=TRUE)[1:2])) 
    #Slice based in the specified number of colums (this can be improved) 
    for(i in seq(1, QTD_COLUMNS, by=1)) 
    { 
    temp_result = sapply(text, function(x){ 
     start = 1 
     stop =stops[i] 
     if(i > 1)    
     start = stops[i-1] + 1 
     if(i == QTD_COLUMNS)#last column, read until end. 
     stop = nchar(x)+1 
     substr(x, start=start, stop=stop) 
    }, USE.NAMES=FALSE) 
    temp_result = trim(temp_result) 
    result = append(result, temp_result) 
    } 
    result 
} 

txt = read_lines("alice_in_wonderland.txt") 

result = '' 

for (i in 1:length(txt)) { 
    page = txt[i] 
    t1 = unlist(strsplit(page, "\n"))  
    maxSize = max(nchar(t1)) 
    t1 = paste0(t1,strrep(" ", maxSize-nchar(t1))) 
    result = append(result,read_text(t1)) 
} 

result 

Aber nein Glück mit einigen der Dateien. Ich frage mich, ob es einen allgemeineren/besseren regulären Ausdruck gibt, um das Ergebnis zu erreichen.

Vielen Dank im Voraus!

+0

Ich wäre versucht, eine Nicht-PDF-Alternative zu finden. Und wenn Sie diese spezifische Geschichte verwenden möchten, gibt es hier eine einfache Textversion: http://www.gutenberg.org/files/11/11-0.txt. Wenn Sie dies nicht tun, suchen Sie nach einem anderen PDF-to-Text-Konvertierungstool, das in 1-Spalten-Ausgabe konvertiert wird. – neilfws

+1

Sieht aus wie eine Datei fester Breite - 'dat <- read.fwf (Datei, widths = c (37,48), stringsAsFactors = FALSE)' würde Ihnen einen sehr guten Start geben, wenn in den beiden Spalten immer eine konstante Breite ist . – thelatemail

+1

Was [meine geistige Gesundheit gerettet] (https://www.nu42.com/2014/09/scraping-pdf-documents-without-losing.html) war realisiert, dass 'pdftohtml' einen sehr nützlichen XML-Ausgabemodus hat. –

Antwort

0

Mit dem festen -Breite linke Spalte, können wir jede Zeile in die ersten 37 Zeichen und den Rest aufteilen, diese zu Strings für die linke und rechte Spalte hinzufügen. Zum Beispiel mit Regex

use warnings; 
use strict; 

my $file = 'two_column.txt' 
open my $fh, '<', $file or die "Can't open $file: $!"; 

my ($left_col, $right_col); 

while (<$fh>) 
{ 
    my ($left, $right) = /(.{37})(.*)/; 

    $left =~ s/\s*$/ /; 

    $left_col .= $left; 
    $right_col .= $right; 
} 
close $fh; 

print $left_col, $right_col, "\n"; 

Dies druckt den gesamten Text. Oder Joinspalten, my $text = $left_col . $right_col;

Das RegexMuster (.{37}) jedes Zeichen entspricht (.) und tut dies genau 37-mal ({37}), die Erfassung, dass mit (); Die (.*) erfasst alle verbleibenden. Diese werden von der Regex zurückgegeben und zugewiesen. Die nachgestellten Leerzeichen in $left werden zu einem zusammengefasst. Beide werden dann angehängt (.=).

oder von der Befehlszeile

perl -wne' 
    ($l, $r) = /(.{37})(.*)/; $l =~ s/\s*$/ /; $cL .= $l; $cR .= $r; 
    }{ print $cL,$cR,"\n" 
' two_column.txt 

wo }{ den END Block beginnt, die vor der Abfahrt fährt (nachdem alle Zeilen verarbeitet worden sind).

+0

@pachamaldese Ich habe ein bisschen aus Gründen der Klarheit editiert und ein paar Statements hinzugefügt. – zdim

0

Sieht aus wie eine feste Breite-Datei, wenn es immer eine konstante Breite in den beiden Spalten ist:

dat <- read.fwf(textConnection(txt), widths=c(37,48), stringsAsFactors=FALSE) 
gsub("\\s+", " ", paste(unlist(dat), collapse=" ")) 

, die sie alle in einem großen langen String setzen:

[1] "Alice was beginning to get very tired of sitting by her sister on the bank, and of having nothing to do: once or twice she had peeped into the book her sister was reading, but it had no pictures or conversations in it, `and what is the use of a book,' thought Alice `without pictures or conversation?" 
Verwandte Themen