2009-10-24 21 views
2

我已經學會了如何使用下面的代碼以消除重複的Perl:如何使用Perl合併重疊元素?

my %seen =(); 
my @unique = grep { ! $seen{ $_}++ } @array; 

但是,如果我想的重疊部分合並呢?有沒有像上面的代碼直接做這項工作的簡單方法?

例如位輸入文件看起來是這樣的:

 
Anais Nin : People living deeply have no fear of death. 
Pascal  : Wisdome sends us back to our childhood. 
Nietzsche : No one lies so boldly as the man who is indignant. 
Camus  : Stupidity has a knack of getting its way. 
Plato  : A good decision is based on knowledge and not on numbers. 
Anais Nin : We don't see things as they are, we see them as we are. 
Erich Fromm  : Creativity requires the courage to let go of certainties. 
M. Scott Peck : Share our similarities, celebrate our differences. 
Freud  : The ego is not master in its own house. 
Camus  : You cannot create experience. You must undergo it. 
Stendhal : Pleasure is often spoiled by describing it. 

的願望看起來就像這樣:

 
Anais Nin : People living deeply have no fear of death. We don't see things as they are, we see them as we are. 
Pascal  : Wisdome sends us back to our childhood. 
Nietzsche : No one lies so boldly as the man who is indignant. 
Camus  : Stupidity has a knack of getting its way. You cannot create experience. You must undergo it. 
Plato  : A good decision is based on knowledge and not on numbers. 
Erich Fromm  : Creativity requires the courage to let go of certainties. 
M. Scott Peck : Share our similarities, celebrate our differences. 
Freud  : The ego is not master in its own house. 
Stendhal : Pleasure is often spoiled by describing it. 

謝謝你,一如既往地爲任何指導!

+0

爲什麼downvote?什麼是正確的方式來解釋我的問題?謝謝。 – Mike 2009-10-24 06:19:04

回答

7

這是一個非常簡單的正則表達式和散列應用程序。我把你的數據放到一個名爲「merge.txt」的文件中。這將結果打印到標準輸出。

#! perl 
use warnings; 
use strict; 
open my $input, "<", "merge.txt" or die $!; 
my %name2quotes; 
while (my $line = <$input>) { 
    if ($line =~ /(.*?)\s*:\s*(.*?)\s*$/) { 
     my $name = $1; 
     my $quote = $2; 
     if ($name2quotes{$name}) { 
      $name2quotes{$name} .= " " . $quote; 
     } else { 
      $name2quotes{$name} = $quote; 
     } 
    } # You might want to put an "else" here to check for errors. 
} 
close $input or die $!; 
for my $name (sort keys %name2quotes) { 
    print "$name : $name2quotes{$name}\n"; 
} 
+0

測試好了!對我而言,這並不簡單。感謝您的教訓:) – Mike 2009-10-24 06:16:30

+2

您可能還想在'if'後面添加'else'來檢查解析行是否有錯誤。 – 2009-10-24 07:15:33

2
while (<>) { 
    ($F1,$F2) = split(/[:\n]/, $_); 
    $F1 =~ s/[[:space:]]+//g; 
    if (!(defined $a{$F1})) { 
     $a{$F1} = $F2; 
    } 
    else { 
     $a{$F1} = "$a{$F1} $F2"; 
    } 
} 
foreach $i (keys %a) { 
    print $i, $a{$i} . "\n"; 
} 

輸出

$ perl test.pl file 
    Freud The ego is not master in its own house. 
    ErichFromm Creativity requires the courage to let go of certainties. 
    Camus Stupidity has a knack of getting its way. You cannot create experience. You must undergo it. 
    M.ScottPeck Share our similarities, celebrate our differences. 
    Plato A good decision is based on knowledge and not on numbers. 
    Pascal Wisdome sends us back to our childhood. 
    Nietzsche No one lies so boldly as the man who is indignant. 
    AnaisNin People living deeply have no fear of death. We don't see things as they are, we see them as we are. 
    Stendhal Pleasure is often spoiled by describing it. 
+0

@ ghostdog74,這也適用。感謝分享代碼:)我不確定,但行「$ FS =':';'似乎沒有用處 – Mike 2009-10-24 06:33:06

3

您可以連接報價沒有測試的散列元素的存在。如果哈希元素不存在,Perl將自動生成哈希元素。

my %lib; 
for (<DATA>){ 
    chomp; 
    my ($au, $qu) = split /\s+:\s+/, $_, 2; 
    $lib{$au} .= ' ' . $qu; 
} 

print $_, " : ", $lib{$_}, "\n" for sort keys %lib; 

__DATA__ 
# Not shown. 
+0

哇,這段代碼真的很棒!感謝分享,FM! – Mike 2009-10-24 13:00:12

1

我已經通過在使其他的Perl相關的職位和線程只是瀏覽,發現Schwern擁有的答案,標題爲「How do I load a file into a Perl hash?」實際上可以解決我的問題的問題。看起來不同的人可能會用不同的方式來表達同一個問題。

少數必要的修改和添加的打印指令的散列,我想出了以下工作代碼:

#!perl 
use warnings; 
use autodie; 
use strict; 

open my $quotes,'<','c:/quotes.txt'; 
my %hash; 
while (<$quotes>) 
{ 
    chomp; 
    my ($au, $qu) = split /\s+:\s+/, $_, 2; 
    $hash{$au} .= exists $hash{$au}? "$qu" : $qu; 

} 
print map { "$_ : $hash{$_}\n" } keys %hash;