0

我有一个不能正常工作的脚本 perl 的问题。该脚本在参数上采用 2 个文件:

第一个是词法:

a
à
abaissa
abaissable
abaissables
abaissai
abaissaient
abaissais
abaissait
abaissâmes   

第二个是语料库:

ASEAN New Markets (renommé « Equity ASEAN » à partir du 24 juin 2011), Gems World, Emerging Internai Demand (renommé « Equity Emerging Internai\
 Demand » à partir du 24 juin 2011), Emerging Markets (intégré au Compartiment « Emerging World » le 24 juin 2011) et Emerging World (renommé «\
 Equity Emerging World » à partir du 24 juin 2011).
Les Actions de catégorie « B » ne sont pas soumises à des Frais sur vente réglés d'avance (c'est-à-dire des Frais sur vente qui réduisent le mo\
ntant de la souscription au Fonds d'un investisseur) mais sont soumises à des FVDE prélevés sur les rachat d'Actions de catégorie « B » effectu\
és dans les quatre (4) années suivant la date d'achat (qui, pour les Actions de catégorie « B » acquises le 29 février lors de n'importe quelle\
 année, seront réputées avoir été achetées le jour précédent) comme suit :
Les Actions de catégorie « B » peuvent être échangées à la valeur liquidative par Action des Actions de catégorie « B » du Portefeuille sans qu\
'aucun Frais de vente ne soit prélevé à ce moment-là.
« Jour ouvrable » :
Les « transactions couvertes » comprennent les prêts ou extensions de crédit, les achats d'actifs et certains autres types de transactions (y c\
ompris les transactions sur produits dérivés et les garanties) qui entraîneraient pour les entités bancaires ou leurs sociétés affiliées un ris\
que de crédit par rapport à des fonds gérés par leurs sociétés affiliées.
«CSSF» désigne la Commission de Surveillance du Secteur Financier.
« Jour de négociation » :
«Directive 78/660/CEE» (Directive 78/660/EEC) désigne la directive 78/660/CEE du 25 juillet 1978 fondée sur l’Article 54 paragraphe 3 g) du Tra\
ité concernant les comptes annuels de certaines formes de sociétés, telle que modifiée.
les « démarcheurs » ou les « commissions d'indication de clients » pour avoir orienté les investisseurs vers les Portefeuilles, Comptes client/\
GS et autres produits ;
« Global Diversified Equity » - Ce Compartiment vise l'appréciation du capital sur le moyen et long terme en investissant principalement dans u\
n portefeuille diversifié d'actions et d'instruments apparentés à des actions émis par des sociétés du monde entier.

和脚本:

use strict;
use utf8;
open(LEX, "<$ARGV[0]" ) or die "Usage: ./script PATH_TO_LEXIQUE PATH_TO_CORPUS\nAn error occured, open: $!";

my $tmp = "";


while ( <LEX> )
{
    $tmp = $_;

    open(CORPUS, "<$ARGV[1]" ) or die "Usage: ./script PATH_TO_LEXIQUE PATH_TO_CORPUS\nAn error occured, open: $!";

    S: while ( <CORPUS> )
    {
        if ($_ =~ m/$tmp/)
        {
            print "Matched !";
    }
        last S if $_ =~ m/$tmp/;
    }
    if ($_ =~ m/$tmp/)
    {

    }
    else
    {
        print $tmp;
    }
    close(CORPUS);
}
close(LEX);

但是正则表达式永远不会匹配,尽管他应该这样做,因为两个文档中都存在字符“à”。

我尝试了几个测试,似乎 $tmp = a(词汇的第一行)的长度($tmp)等于 4?!任何人都可以帮助我吗?

4

3 回答 3

4

我认为问题在于您没有读取具有正确编码的文件。

使用 utf8 不是为了这个。

如何使用菱形运算符 (<>) 读取 UTF-8?

打开文件后使用binmode,utf8。

binmode LEX, ':utf8';
binmode CORPUS, ':utf8';

使用 data::dumper 打印出实际数据进行检查。

使用 Data::Dumper;...

S: while ( <CORPUS> )
{

    if ($_ =~ m/$tmp/){
        print "Matched !";
    }
    die Dumper($tmp,$_); 
    last S if $_ =~ m/$tmp/;
}
于 2013-02-05T13:38:09.173 回答
3

行以换行符结束。您正在搜索两个字符“a\n”而不是“a”。用于chomp删除尾随的换行符。

已修复,以及许多其他问题和糟糕的代码:

use strict;
use warnings;
use utf8;
use open ':std', ':utf8';

@ARGV == 2
    or die("Usage: ./script PATH_TO_LEXIQUE PATH_TO_CORPUS\n");

open(my $LEX, "<", $ARGV[0])
    or die("Can't open $ARGV[0]: $!\n");

WORD: while (my $word = <$LEX>) {
    chomp($word);
    my $pat = quotemeta($word);

    open(my $CORPUS, "<", $ARGV[1])
       or die("Can't open $ARGV[1]: $!\n");

    while (<$CORPUS>) {
        if (/$pat/) {
            print "Matched $word!\n";
            next WORD;
        }
    }

    print "Didn't match $word\n";
}

要调试,

  1. 删除每个文件中除第一行之外的所有内容。

  2. 将以下内容添加到您的代码中:

    use Data::Dumper qw( Dumper );
    
    sub dump_str {
        local $Data::Dumper::Useqq = 1;
        local $Data::Dumper::Terse = 1;
        local $Data::Dumper::Indent = 0;
        return Dumper($_[0]);
    }
    
  3. 在之前添加以下内容if (/$pat/)

    printf("\$_=%s; \$pat=%s\n", dump_str($_), dump_str($pat));
    
于 2013-02-05T13:44:29.620 回答
1

$tmp=$_ 之前的行你需要一个 chomp 来删除 eol 字符

于 2013-02-05T13:44:01.400 回答