извлечь помеченные слова с помощью регулярных выражений Perl - PullRequest
1 голос
/ 01 ноября 2011

Я пытаюсь написать регулярное выражение, используя perl, но мне нужна помощь.Что я хочу сделать, так это предположить, что у меня есть эти тексты в качестве примеров:

1- [NP some / NN text / NNP here / NNP]

Мне интересны словапомечены / NNP, поэтому я хочу, чтобы мое регулярное выражение осуществляло поиск по каждой строке, пока не найдет: [NP затем пробел, затем (может или не может найти) слово, помеченное / NN, затем одно или несколько слов, помеченных / NNP (и содержащеенекоторые специальные символы).

Я хочу извлечь слова, помеченные / NNP, из каждой строки, чтобы результат был:

1- текст здесь

что я сделалдо сих пор стоит извлечь помеченные слова с / NNP из всех примеров

while ($line =~ m/\s(\S*?)\/NNP/gs)
{
        my $word = $1;
        print $word." ";
} 
print "\n";

Любые просьбы Ideas?

Ответы [ 5 ]

2 голосов
/ 02 ноября 2011

Сначала гольф:

my @list = map { [ /(\S+)\/NNP/g ] } map { ( /\[NP ([^\]]+)]/g ) } <DATA>;
  • Мы берем все строки на входе
  • Мы получаем все экземпляры '[NP...]'
  • Для каждого экземплярамы отображаем его в массив всех экземпляров '*/NNP'.

Чуть более длинная рука, это выглядит так:

my @list;
while ( my $line = <DATA> ) { 
    foreach my $g ( $line =~ /\[NP ([^\]]+)]/g ) { 
        push @list, [ $g =~ /(\S+)\/NNP/g ];
    }
}

Дамп выглядит так:

@list: [
         [
           'Ebd',
           'AlmEz',
           'AbrAhym'
         ],
         [
           'hAnY',
           'HjAb'
         ],
         [
           'xAld',
           'ftH',
           'Allh'
         ],
         [
           'ESAm',
           '$rf'
         ],
         [
           'AlqAhrp'
         ]
       ]

(Отвечая на комментарий) Есть два способа распечатать структуру, как у меня выше.Более стандартный способ - это что-то вроде:

use Data::Dumper ();
say Data::Dumper->Dump( [ \@list ], [ '*list' ] );

Второй, который я использую:

use Smart::Comments;
### @list

См. Smart::Comments.(Что в значительной степени делает то же самое за кулисами.)

1 голос
/ 02 ноября 2011

Хорошо, уже много хороших ответов. Вот решение на основе split.

use strict;
use warnings;
use v5.10;  # for say(), not required

while (<DATA>) {
    for (grep /^\[NP /,                 # ..and keep only the NP-blocks
        split(/(\[NP [^]]*\])/, $_)) {  # Split on NP-blocks
        my @a = map { (split m(/), $_)[0] }    # ...keep first part
            grep m{/NNP\]?$},                  # ...and keep only /NNP
            split;                      # Split the NP-block on whitespace
        say "@a";
    }
}

__DATA__
[NP Almst$Ar/NN Ebd/NNP AlmEz/NNP AbrAhym/NNP] [NP Almhnds/NN hAnY/NNP HjAb/NNP]
[NP xAld/NNP ftH/NNP Allh/NNP] [NP ESAm/NNP $rf/NNP] [NP AlqAhrp/NNP]
1 голос
/ 02 ноября 2011

Возможно:

    #!/usr/bin/env perl
    use strict;
    use warnings;
    while (<DATA>) {
        while ( m{(\[NP.+?\])}g ) {
        my $piece = $1;
        1 while $piece =~ m{(\w+)/NNP}g and printf "%s ",$1;
        print "\n";
        }
    }
    __DATA__
    1- [NP Almst$Ar/NN Ebd/NNP AlmEz/NNP AbrAhym/NNP] [NP Almhnds/NN hAnY/NNP HjAb/NNP]
    2- [NP xAld/NNP ftH/NNP Allh/NNP] [NP ESAm/NNP $rf/NNP] [NP AlqAhrp/NNP]

А потом вы попросили, чтобы можно было пропустить строки только с одним помеченным словом. Для этого я мог бы сделать:

#!/usr/bin/env perl
use strict;
use warnings;
my @line = ();
while (<DATA>) {
    while ( m{(\[NP.+?\])}g ) {
        my $piece = $1;
        while ( $piece =~ m{(\w+)/NNP}g ) {
            push @line, $1;
        }
        print "@line\n", @line = () if @line && @line > 1;
    }
}
__DATA__
1- [NP Almst$Ar/NN Ebd/NNP AlmEz/NNP AbrAhym/NNP] [NP Almhnds/NN hAnY/NNP HjAb/NNP]
2- [NP xAld/NNP ftH/NNP Allh/NNP] [NP ESAm/NNP $rf/NNP] [NP AlqAhrp/NNP]
3- [Nothing of interest here]
0 голосов
/ 02 ноября 2011

Если вы знаете немного Perl, это должно указать вам правильное направление:

$str = '
1- [NP Almst$Ar/NN Ebd/NNP AlmEz/NNP AbrAhym/NNP] [NP Almhnds/NN hAnY/NNP HjAb/NNP]
2- [NP xAld/NNP ftH/NNP Allh/NNP] [NP ESAm/NNP $rf/NNP] [NP AlqAhrp/NNP]
';

while ($str =~ /\[NP([^\]]+)\]/g)
{
    for ( $1 =~ /\s(\S*?)\/NNP/g)  {
        print "$_ ";
    }
    print "\n";
}
0 голосов
/ 02 ноября 2011

Может как то так?

#!/usr/bin/perl -w

use strict;

my $text = <<'DAISY';
[NP Almst$Ar/NN Ebd/NNP AlmEz/NNP AbrAhym/NNP] [NP Almhnds/NN hAnY/NNP HjAb/NNP]
[NP xAld/NNP ftH/NNP Allh/NNP] [NP ESAm/NNP $rf/NNP] [NP AlqAhrp/NNP]
DAISY

for my $tag ($text =~ /(\[NP.+?\/NNP\])/gm) {

    my @words = $tag =~ / (\w+)\/NNP/g;
    print "@words\n";
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...