Nlp 如何从Project Gutenberg文本中删除页眉/页脚?

Nlp 如何从Project Gutenberg文本中删除页眉/页脚?,nlp,text-processing,heuristics,corpus,stripping,Nlp,Text Processing,Heuristics,Corpus,Stripping,我尝试过各种方法从古腾堡项目文本中删除许可证,作为语言学习项目的语料库,但我似乎无法想出一种无监督、可靠的方法。到目前为止,我提出的最好的启发式方法是剥离前28行和后398行,这对大量文本都有效。任何关于我可以自动剥离文本的方法的建议(对于许多文本来说非常相似,但在每种情况下略有不同,还有一些不同的模板),以及关于如何验证文本已被准确剥离的建议,都将非常有用。你不是在开玩笑吧。这几乎就好像他们试图让人工智能完成这项工作。我只能想到两种方法,它们都不完美 1) 例如,用Perl设置一个脚本,以处理

我尝试过各种方法从古腾堡项目文本中删除许可证,作为语言学习项目的语料库,但我似乎无法想出一种无监督、可靠的方法。到目前为止,我提出的最好的启发式方法是剥离前28行和后398行,这对大量文本都有效。任何关于我可以自动剥离文本的方法的建议(对于许多文本来说非常相似,但在每种情况下略有不同,还有一些不同的模板),以及关于如何验证文本已被准确剥离的建议,都将非常有用。

你不是在开玩笑吧。这几乎就好像他们试图让人工智能完成这项工作。我只能想到两种方法,它们都不完美

1) 例如,用Perl设置一个脚本,以处理最常见的模式(例如,查找短语“producted by”,继续往下看下一个空行并在那里剪切),但要对预期内容进行大量断言(例如,下一个文本应该是标题或作者)。这样,当模式失败时,您就知道了。模式第一次失败时,请手动执行。第二次,修改脚本


2) 试试。

多年来,我还想要一个工具来剥离Project Gutenberg的页眉和页脚,以便在不污染分析的情况下使用etxt中混合的样板文件进行自然语言处理。读了这个问题后,我终于抽出手指,编写了一个Perl过滤器,您可以通过管道将其导入任何其他工具

它是使用每行正则表达式作为状态机生成的。它的编写很容易理解,因为速度不是典型的etexts大小的问题。到目前为止,它在我这里的几十个etexts上工作,但是在野外,肯定还有更多的变体需要添加。希望代码足够清晰,任何人都可以添加:


#!/usr/bin/perl

# stripgutenberg.pl < in.txt > out.txt
#
# designed for piping
# Written by Andrew Dunbar (hippietrail), released into the public domain, Dec 2010

use strict;

my $debug = 0;

my $state = 'beginning';
my $print = 0;
my $printed = 0;

while (1) {
    $_ = <>;

    last unless $_;

    # strip UTF-8 BOM
    if ($. == 1 && index($_, "\xef\xbb\xbf") == 0) {
        $_ = substr($_, 3);
    }

    if ($state eq 'beginning') {
        if (/^(The Project Gutenberg [Ee]Book( of|,)|Project Gutenberg's )/) {
            $state = 'normal pg header';
            $debug && print "state: beginning -> normal pg header\n";
            $print = 0;
        } elsif (/^$/) {
            $state = 'beginning blanks';
            $debug && print "state: beginning -> beginning blanks\n";
        } else {
            die "unrecognized beginning: $_";
        }
    } elsif ($state eq 'normal pg header') {
        if (/^\*\*\*\ ?START OF TH(IS|E) PROJECT GUTENBERG EBOOK,? /) {
            $state = 'end of normal header';
            $debug && print "state: normal pg header -> end of normal pg header\n";
        } else {
            # body of normal pg header
        }
    } elsif ($state eq 'end of normal header') {
        if (/^(Produced by|Transcribed from)/) {
            $state = 'post header';
            $debug && print "state: end of normal pg header -> post header\n";
        } elsif (/^$/) {
            # blank lines
        } else {
            $state = 'etext body';
            $debug && print "state: end of normal header -> etext body\n";
            $print = 1;
        }
    } elsif ($state eq 'post header') {
        if (/^$/) {
            $state = 'blanks after post header';
            $debug && print "state: post header -> blanks after post header\n";
        } else {
            # multiline Produced / Transcribed
        }
    } elsif ($state eq 'blanks after post header') {
        if (/^$/) {
            # more blank lines
        } else {
            $state = 'etext body';
            $debug && print "state: blanks after post header -> etext body\n";
            $print = 1;
        }
    } elsif ($state eq 'beginning blanks') {
        if (/<!-- #INCLUDE virtual=\"\/include\/ga-books-texth\.html\" -->/) {
            $state = 'header include';
            $debug && print "state: beginning blanks -> header include\n";
        } elsif (/^Title: /) {
            $state = 'aus header';
            $debug && print "state: beginning blanks -> aus header\n";
        } elsif (/^$/) {
            # more blanks
        } else {
            die "unexpected stuff after beginning blanks: $_";
        }
    } elsif ($state eq 'header include') {
        if (/^$/) {
            # blanks after header include
        } else {
            $state = 'aus header';
            $debug && print "state: header include -> aus header\n";
        }
    } elsif ($state eq 'aus header') {
        if (/^To contact Project Gutenberg of Australia go to http:\/\/gutenberg\.net\.au$/) {
            $state = 'end of aus header';
            $debug && print "state: aus header -> end of aus header\n";
        } elsif (/^A Project Gutenberg of Australia eBook$/) {
            $state = 'end of aus header';
            $debug && print "state: aus header -> end of aus header\n";
        }
    } elsif ($state eq 'end of aus header') {
        if (/^((Title|Author): .*)?$/) {
            # title, author, or blank line
        } else {
            $state = 'etext body';
            $debug && print "state: end of aus header -> etext body\n";
            $print = 1;
        }
    } elsif ($state eq 'etext body') {
        # here's the stuff
        if (/^<!-- #INCLUDE virtual="\/include\/ga-books-textf\.html" -->$/) {
            $state = 'footer';
            $debug && print "state: etext body -> footer\n";
            $print = 0;
        } elsif (/^(\*\*\* ?)?end of (the )?project/i) {
            $state = 'footer';
            $debug && print "state: etext body -> footer\n";
            $print = 0;
        }
    } elsif ($state eq 'footer') {
        # nothing more of interest
    } else {
        die "unknown state '$state'";
    }

    if ($print) {
        print;
        ++$printed;
    } else {
        $debug && print "## $_";
    }
}

#!/usr/bin/perl
#stripgutenberg.plout.txt
#
#专为管道设计
#由Andrew Dunbar(hippietrail)撰写,于2010年12月发布于公共领域
严格使用;
我的$debug=0;
我的$state='开始';
我的$print=0;
我的$printed=0;
而(1){
$_ = ;
最后,除非$\;
#带UTF-8物料清单
如果($.==1&&index($\,“\xef\xbb\xbf”)==0){
$u1=substr($3);
}
如果($state eq'beging'){
if(/^(古腾堡项目[Ee]书籍(共|,)|古腾堡项目)/){
$state='正常pg标题';
$debug&&print“状态:开始->正常pg头\n”;
$print=0;
}elsif(/^$/){
$state='开头空白';
$debug&&print“状态:开始->开始空白\n”;
}否则{
die“未识别的开始:$\u”;
}
}elsif($state eq‘正常pg头’){
如果(/^\*\*\*\\*\\\?开始古腾堡电子书项目,/){
$state='正常标题的结尾';
$debug&&print“状态:正常pg头->正常pg头结束\n”;
}否则{
#正常pg头体
}
}elsif($state eq‘正常标头结束’){
if(/^(由|转录自|)/){
$state='post header';
$debug&&print“状态:正常pg头的结束->post头\n”;
}elsif(/^$/){
#空行
}否则{
$state='etextbody';
$debug&&print“状态:正常标题结束->文本正文\n”;
$print=1;
}
}elsif($state eq‘post header’){
如果(/^$/){
$state='post header后面的空格';
$debug&&print“状态:post头->post头后空白\n”;
}否则{
#多行生成/转录
}
}elsif($state eq‘post header’后空白){
如果(/^$/){
#更多的空行
}否则{
$state='etextbody';
$debug&&print“状态:post头后空白->etext正文\n”;
$print=1;
}
}elsif($state eq‘开头空白’){
如果(//){
$state='header include';
$debug&&print“状态:开始空白->标题包含\n”;
}elsif(/^Title:/){
$state='aus header';
$debug&&print“状态:开始空白->aus标题\n”;
}elsif(/^$/){
#更多空白
}否则{
die“开始空格后出现意外内容:$\ux”;
}
}elsif($state eq‘header include’){
如果(/^$/){
#标题后面的空格包括
}否则{
$state='aus header';
$debug&&print“state:header include->aus header\n”;
}
}elsif($state eq'aus header'){
如果(/^要联系澳大利亚的古腾堡项目,请访问http:\/\/Gutenberg\.net\.au$/){
$state='aus头的末尾';
$debug&&print“状态:aus头->aus头结束\n”;
}elsif(/^A澳大利亚古腾堡项目电子书$/){
$state='aus头的末尾';
$debug&&print“状态:aus头->aus头结束\n”;
}
}elsif($state eq‘aus头端’){
如果(/^((标题|作者):.*)?$/){
#标题、作者或空行
}否则{
$state='etextbody';
$debug&&print“状态:aus头的结尾->etext正文\n”;
$print=1;
}
}elsif($state eq'etext body'){
#这是东西
如果(/^$/){
$state='footer';
$debug&&print“状态:etext body->footer\n”;
$print=0;
}elsif(/^(\*\*\*?)?项目结束/i){
$state='footer';
$debug&&print“状态:etext body->footer\n”;
$print=0;
}
}elsif($state eq'footer'){
#没什么比这更有趣的了
}否则
install.packages('gutenbergr')
library(gutenbergr)
t <- gutenberg_download('25519')  # give it the id number of the text
library(data.table)
t <- as.data.table(t)  # I hate tibbles -- datatables are easier to work with
head(t)  # get the column names

# filter out lines that are illustrations and joins all lines with a space
# the \\[ searches for the [ character, the \\ are used to 'escape' the special [ character
# the !like() means find rows where the text column is not like the search string
no_il <- t[!like(text, '\\[Illustration'), 'text']
# collapse the text into a single character string
t_cln <- do.call(paste, c(no_il, collapse = ' '))