Обработка лексический анализ предложения, используя в Perl функция Split


У меня есть два вида лексический анализ предложения, которые мне нужно обработать. Один тип данных "маркированный формат", и в "анализируется формат".


Меченый

Вход (@subsentences) выглядит так:

5.4_CD Passive_NNP Processes_NNP of_IN Membrane_NNP Transport_NNP 85_CD We_PRP have_VBP examined_VBN membrane_NN structure_NN and_CC how_WRB it_PRP is_VBZ used_VBN to_TO perform_VB one_CD membrane_NN function_NN :_: the_DT binding_JJ of_IN one_CD cell_NN to_TO another_DT ._.

Желаемый результат

5.4 пассивных процессов мембранного транспорта 85 Мы исследовали мембраны д....

Мой код

@finalsentence = split(/_\S+/,$subsentences[$j]);

Разбирается

   Parsing [sent. 1 len. 31]:
        nsubj(85-7, Processes-3)
        nn(Transport-6, Membrane-5)
        prep_of(Processes-3, Transport-6)
        nsubj(examined-10, We-8)
        nsubjpass(used-17, it-15)
        xsubj(perform-19, it-15)
        conj_and(examined-10, used-17)
        xcomp(used-17, perform-19)
        dobj(perform-19, function-22)
        prep_of(binding-25, cell-28) <- refer to this for examples below

Желаемый результат (на последней строке)

  • отправлено. количество (т. е. послал. 1 )
  • функция грамматики (т. е. prep_of )
  • первая зависимость слова (т. е.. привязка )
  • вторая зависимость слова (т. е.. ячейки )

Мой код

Вот как я делаю это, но когда я проверяю границы слова (\B), то иногда они не определены и на вершине, что, это довольно сырой:

Для отправки. количество:

@parsesentcounter = split (/.*sent\.\s/, $typeddependencies[$i]);
@parsesentcounter = split (/\s/, $typeddependencies[$i]); 

Этот (сырой способ) оставляет послал. количество (отправлено. 1) на $parsesentcounter[2]

Для функции грамматики:

@grammarfunction = split(/\(\S+\s\S+\s/,$typeddependencies[$i]);

Это оставляет грамматические функции(prep_of) на $grammarfunction[0]

За слова зависимость, я делаю это в несколько шагов (я думаю, я заблудился тут немного):

@dependencywords = split (/,\s+/,$typeddependencies[$i]); ## Take out all commas, there was also a space associated
@dependencywords = split (/-\S+\s+/,$typeddependencies[$i]); ## Take out all -digits and space

Это оставляет вторая зависимость слова(ячейки) на $dependencywords[1].

Тогда для первого зависимого слова:

@firstdependencyword = split(/.*subj\w*.|.*obj\w*.|.*prep\w*\(|.*xcomp\w*\(|.*agent\(|purpcl\(|.*conj_and\(/,$dependencywords[0]);

Это оставляет первого зависимого слова (привязка) на $firstdependencyword[1]



Комментарии
1 ответ

Матч и заменить намного лучше подходят для этой задачи, чем сплит().
Чтобы удалить все _XX вещи, используйте заменитель глобального ов/(_\с+)//г;.
Поэтому при создании вашего желаемого результата на самом деле легко.

Чтобы увидеть демо и как разобрать отчет, см. ниже код. Обратите внимание, что если на левой стороне содержит переменные в список контекстного типа:($gramFunc, $dep1, $dep2) , то они будут направлены $1,$2,$3 матча соответственно. Я могу проверить, если $dep2 означает, что матч удался, потому что, если эта переменная определена, то переменные $gramFunc и dep1 $слишком!

Эта линия $sentNum = $1, Если /\[отправленные\.\с*выражение(\D+)/; имеет такое же значение, как:

if (/\[sent\.\s*(\d+)/)
{
$sentNum = $1;
}

Я не могу присвоить $sentNum непосредственно в этом случае, потому что я хочу знать, если матч работал или нет. $1 неопределено, если матч не удается, и скалярное значение /\[отправленные\.\С*(\D+ В)/ будет равна нулю. Я предполагаю, что появится в докладе, который вы пытаетесь разобрать больше таких "[послал" линии. Это заявление просто обновляет по мере необходимости текущий отправлено # для отчета.

Код:

#!/usr/bin/perl -w
use strict;

my $str = '5.4_CD Passive_NNP Processes_NNP of_IN Membrane_NNP Transport_NNP 85_CD We_PRP have_VBP examined_VBN membrane_NN structure_NN and_CC how_WRB it_PRP is_VBZ used_VBN to_TO perform_VB one_CD membrane_NN function_NN :_: the_DT binding_JJ of_IN one_CD cell_NN to_TO another_DT ._.';

$str =~ s/(_\S+)//g; # deletes all of the "_XX" tokens
print $str, "\n";

my $sentNum = 0;
while (<DATA>)
{
$sentNum = $1 if /\[sent\.\s*(\d+)/;

my ($gramFunc, $dep1, $dep2) = $_ =~ /\s+(\w+)\((\w+).*?(\w+)-/;
if (defined $dep2)
{
printf "sent num=$sentNum %-10s %-15s %-15s\n", $gramFunc, $dep1, $dep2;
}
}

=program output
5.4 Passive Processes of Membrane Transport 85 We have examined membrane structure and how it is used to perform one membrane function : the binding of one cell to another .
sent num=1 nsubj 85 Processes
sent num=1 nn Transport Membrane
sent num=1 prep_of Processes Transport
sent num=1 nsubj examined We
sent num=1 nsubjpass used it
sent num=1 xsubj perform it
sent num=1 conj_and examined used
sent num=1 xcomp used perform
sent num=1 dobj perform function
sent num=1 prep_of binding cell
=cut

__DATA__
Parsing [sent. 1 len. 31]:
nsubj(85-7, Processes-3)
nn(Transport-6, Membrane-5)
prep_of(Processes-3, Transport-6)
nsubj(examined-10, We-8)
nsubjpass(used-17, it-15)
xsubj(perform-19, it-15)
conj_and(examined-10, used-17)
xcomp(used-17, perform-19)
dobj(perform-19, function-22)
prep_of(binding-25, cell-28) <- refer to this for examples below

1
ответ дан 5 июля 2011 в 01:07 Источник Поделиться