2012-10-24 45 views
0

我正在研究将句子拆分为单个单词的代码,然后使用散列键搜索单词以查找它们的存在。我的代码返回100%相同的条件,匹配后,我使用与匹配键相对应的值标记句子中的单词。问题是代码标签术语,但随机值不符合我的预期。此外,在某些情况下,术语和散列键相似但不是100%相同,我如何编写正则表达式来匹配我的术语和键。 注意:我已经将哈希键设置为它们的根形式。我提供了一些例子:如果句子中的术语是协同或反协同的,而我的哈希键是Synerg,那么我怎样才能将上述术语与Synerg相匹配。Perl哈希和正则表达式

我的代码如下:

open IN, "C:\\Users\\Desktop\\TM\\clean_cells.txt" or die "import file absent"; 
    my %hash=(); 
    use Tie::IxHash; 
    tie %hash => "Tie::IxHash"; 
    while(<IN>) 
    { 
    chomp $_; 
    $line=lc $_; 
    @Organs=split/\t/, $line; 
    $hash{$Organs[0]}=$Organs[1]; 
    } 

    $Sentence="Lymphoma is Lymph Heart and Lung"; 
    @list=split/ /,$Sentence; 

    @array=(); 
foreach $term(@list) 
{ 
chomp $term; 
    for $keys(keys %hash) 
    { 
    if($hash{$term}) 
    { 
    $cell="<$hash{$keys}>$term<\/$hash{$keys}>"; 
    push(@array, $cell); 
    } 
    elsif($term=~m/\b\Q$keys(\w+)\E\b/) 
    { 
    $cell="<$hash{$keys}>$term<\/$hash{$keys}>"; 
    push(@array, $cell);   
    } 
    elsif($term=~m/\b\Q(\w+)$keys\E\b/) 
    { 
    $cell="<$hash{$keys}>$term<\/$hash{$keys}>"; 
    push(@array, $cell);   
    } 
    elsif($term=~m/\b\Q(\w+)$keys(\w+)\E\b/) 
    { 
    $cell="<$hash{$keys}>$term<\/$hash{$keys}>"; 
    push(@array, $cell);   
    } 
} 
} 
print @array; 

for example: hash looks like this: %hash={ 
             TF1 => Lymph 
           Thoracic_duct => Lymph 
            SK-MEL-1 => Lymph 
             Brain => Brain 
            Cerebellum => Brain 
             }; 
    So if the term TF1 is found it should be substituted to Lymph TF1 /Lymph 

回答

1

我发现,是防止工作的代码两个大问题:

  • 你快把钥匙给您的散列小写,但你是不是做 相同的条款$Sentence。因此,来自 $Sentence的大写字将永远不匹配。
  • \Q...\E修饰符禁用正则表达式元字符。虽然在插入变量时这样做通常很好,但不能在其中使用像(\w+)这样的表达式 - 它将查找文字字符(\w+)。那些正则表达式需要像这样重写:m/\b\Q$keys\E(\w+)\b/

还有其他的设计问题与您的代码,以及:

  1. 您使用所有的地方未声明的全局变量。您应该用my声明所有变量。始终打开use strict; use warnings;,这会强制您正确执行此操作。
  2. 似乎没有任何理由Tie::IxHash,这会导致您的哈希被排序。您不要在代码中以任何方式使用此顺序。输出按@list排序。我会放弃这个不必要的模块。
  3. 您的if/elsif陈述是多余的。 if($term=~m/\b\Q(\w*)$keys(\w*)\E\b/)将完成相同的事情,所有他们合并。请注意,我将\w+替换为\w*。这允许组之前和之后匹配零个或多个字符而不是一个或多个字符。

注:我没有打扰测试与Tie::IxHash,因为我没有这样的模块,它似乎没有必要。有可能使用这个模块也会在代码中引入其他问题。