2011-11-01 74 views
1

我想用perl寫一個正則表達式,但我需要一些幫助。 我想要做的就是以下,假設我有這些文章作爲例子:使用正則表達式提取標籤詞perl

1- [NP一些/ NN文/ NNP這裏/ NNP]

我很感興趣,通過標記的話/ NNP,所以我想我的正則表達式搜索每一行,直到找到: [NP然後一個空格然後(可能會或可能找不到)標有/ NN的單詞,然後是一個或多個標有/ NNP的單詞(並且會包含一些特殊字符)。

我想提取每行標註/ NNP這樣的結果將是話:

1-這裏文本

是我迄今所做的就是提取與標記的話/ NNP從所有的例子

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

任何想法請求?

回答

1

也許:

#!/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

謝謝,它可行,但如果我不想提取只包含一個帶標籤的單詞/ NNP的'[NP AlqAhrp/NNP]? – Daisy

+0

@達西:看到上面編輯過的帖子。 – JRFerguson

0

也許這樣?

#!/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"; 
} 
0

假設你知道一點點的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"; 
} 
2

第一高爾夫球:

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。 (這在幕後幾乎做了同樣的事情。)

+0

@Axeman:謝謝。我在Perl中是一個新手,請問我怎樣才能打印'@ list',當我使用普通打印時:'ARRAY(0x104a1488)ARRAY(0x104a1470)'。另外,如果我不想提取僅包含一個帶標籤的單詞/ NNP的'[NP AlqAhrp/NNP]? – Daisy

+0

@達西,休息後見修改後的答案。 – Axeman

+0

@Axeman:謝謝。 – Daisy

1

好吧,已經有很多好的答案。這是一個基於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]