Более элегантное решение для удаления элементов из пакета файлов? - PullRequest
0 голосов
/ 22 июня 2011

Хорошо, это больше для моего собственного обучения, чем для реальной необходимости.

У меня есть файлы в следующем формате:

Loading parser from serialized file ./englishPCFG.ser.gz ... done [2.8 sec].
Parsing file: chpt1_1.txt
Parsing [sent. 1 len. 42]: [1.1, Organisms, Have, Changed, over, Billions, of, Years, 1, Long, before, the, mechanisms, of, biological, evolution, were, understood, ,, some, people, realized, that, organisms, had, changed, over, time, and, that, living, organisms, had, evolved, from, organisms, no, longer, alive, on, Earth, .]
(ROOT
  (S
    (S
      (NP (CD 1.1) (NNS Organisms))
      (VP (VBP Have)
        (VP (VBN Changed)
          (PP (IN over)
            (NP
              (NP (NNS Billions))
              (PP (IN of)
                (NP (NNP Years) (CD 1)))))
          (SBAR
            (ADVP (RB Long))
            (IN before)
            (S
              (NP
                (NP (DT the) (NNS mechanisms))
                (PP (IN of)
                  (NP (JJ biological) (NN evolution))))
              (VP (VBD were)
                (VP (VBN understood))))))))
    (, ,)
    (NP (DT some) (NNS people))
    (VP (VBD realized)
      (SBAR
        (SBAR (IN that)
          (S
            (NP (NNS organisms))
            (VP (VBD had)
              (VP (VBN changed)
                (PP (IN over)
                  (NP (NN time)))))))
        (CC and)
        (SBAR (IN that)
          (S
            (NP (NN living) (NNS organisms))
            (VP (VBD had)
              (VP (VBN evolved)
                (PP (IN from)
                  (NP
                    (NP (NNS organisms))
                    (ADJP
                      (ADVP (RB no) (RBR longer))
                      (JJ alive))))
                (PP (IN on)
                  (NP (NNP Earth)))))))))
    (. .)))

num(Organisms-2, 1.1-1)
nsubj(Changed-4, Organisms-2)
aux(Changed-4, Have-3)
ccomp(realized-22, Changed-4)
prep_over(Changed-4, Billions-6)
prep_of(Billions-6, Years-8)
num(Years-8, 1-9)
advmod(understood-18, Long-10)
dep(understood-18, before-11)
det(mechanisms-13, the-12)
nsubjpass(understood-18, mechanisms-13)
amod(evolution-16, biological-15)
prep_of(mechanisms-13, evolution-16)
auxpass(understood-18, were-17)
ccomp(Changed-4, understood-18)
det(people-21, some-20)

Мне нужно удалить все зависимости (последний раздел) это не важно.А затем сохраните новый файл.Вот мой рабочий код:

#!usr/bin/perl
use strict;
use warnings;

##Call with *.txt on command line
##EDIT TO ONLY FIND FILES YOU WANT CHANGED:
my @files = glob("parsed"."*.txt");

foreach my $file (@files) {
my @newfile;
    open(my $parse_corpus, '<', "$file") or die $!;
    while (my $sentences = <$parse_corpus>) {
    #print $sentences, "\n\n";
        if ($sentences =~ /(\w+)\(\S+\-\d+\,\s\S+\-\d+\)/) {
            if ($sentences =~ /subj\w*\(|obj\w*\(|prep\w*\(|xcomp\w*\(|agent\w*\(|purpcl\w*\(|conj_and\w*\(/) {
                push (@newfile, $sentences);
            }

        }
        else {
            push (@newfile, $sentences);
        }
    }
open(FILE ,'>', "select$file" );
print FILE @newfile;
close FILE
}

И часть измененного выходного файла:

nsubj(Changed-4, Organisms-2)
prep_over(Changed-4, Billions-6)
prep_of(Billions-6, Years-8)
nsubjpass(understood-18, mechanisms-13)
prep_of(mechanisms-13, evolution-16)
nsubj(realized-22, people-21)
nsubj(changed-26, organisms-24)
prep_over(changed-26, time-28)
nsubj(evolved-34, organisms-32)
conj_and(changed-26, evolved-34)
prep_from(evolved-34, organisms-36)
prep_on(evolved-34, Earth-41)

Есть ли значительно лучший способ или способ с более элегантным / умным решением?

Спасибо за ваше время, опять же, это чисто для интереса, так что не помогите, если у вас нет времени.

1 Ответ

3 голосов
/ 22 июня 2011

Если я понял вашу логику, вы по умолчанию захотите распечатать в выходной файл, если не встретите «предложение», которое удовлетворяет условию. Если вы удовлетворяете этому первому условию, вы хотите выводить в выходной файл, только если второе условие также верно. В такой ситуации я предпочитаю логику «если это, следующий, если не тот», но это только я. ;) Вот пример с вашим кодом.

use strict;
use warnings;
use autodie;

##Call with *.txt on command line
##EDIT TO ONLY FIND FILES YOU WANT CHANGED:
my @files = glob( "parsed" . "*.txt" );

foreach my $file ( @files ) {
    open my $parse_corpus, '<', "$file";
    open my $outfile, '>', "select$file";
    while ( my $sentences = <$parse_corpus> ) {
        if( $sentences =~ /(\w+)\(\S+\-\d+\,\s\S+\-\d+\)/ ) {
            next unless $sentences =~ /subj\w*\(|obj\w*\(|prep\w*\(|xcomp\w*\(|agent\w*\(|purpcl\w*\(|conj_and\w*\(/;
        }
        print $outfile $sentences;
    }
}

Я не пытался реорганизовать ваши регулярные выражения. Мне показалось более приятным мое чувство эффективности обрабатывать выходной файл построчно одновременно с входным файлом. Это исключает второй цикл, а также необходимость в массиве вывода.

Кроме того, я использовал прагму autodie вместо указания «или умереть» после каждой операции ввода-вывода. И поскольку я использовал лексический дескриптор файла в выходном файле, он закрывается сам. В сочетании с autodie неявное закрытие включено даже «или умри».

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...