0

正しく動作しないスクリプト perl に問題があります。スクリプトは引数で2つのファイルを取ります:

最初は語彙です:

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

2 つ目はコーパスです。

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) で $tmp = a (字句の最初の行) が 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」ではなく「a\n」の 2 文字を検索しています。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=$_ の前の行では、eol 文字を削除するために chomp が必要です

于 2013-02-05T13:44:01.400 に答える