0

次のようなリストがあります。

__DATA__
49103393193[0-9]{1,3};+49103/393193-0;Company 1;Street;Number;Postal Code;City

これらの値を含む大きなリストを、次のようなハッシュにロードします。

%voicePrefix = (
  '49103393193[0-9]{1,3}' => [
                              '+49103/393193-0',
                              'Company 1',
                              'Street'
                              'Number'
                              'Postal Code'
                              'City'
                             ],
);

私はこれを行うことでそれを行います:

my %voicePrefix = map {
  chomp;
  my @fields = split ';';
  shift @fields => \@fields;
} __DATA__;
my $voiceRegex = '(' . join('|',map{quotemeta} keys %voicePrefix) . ')';

ここでの問題は、多数の番号を含む別のリストがあるため、次のような @lines にファイルをロードしたとしましょう。

__@lines__
4910339319344;Test 1
49103393193411;Test 2
49103393193941;Test 3

今私がやりたいことは、番号に正規表現を使用することです

my @lines = __FILEUPTHERE__;
my @line;

my $company;

for(my $i = 0; i < @lines; $i++)
{
    #Split Line
    @line = split( /,/, $lines[$i] );

    #NO MATCH HERE
    $company = $voicePrefix{$1}[1] if ($line[0] =~ /$voiceRegex/);
}

誰かがこの問題で私を助けてくれることを願っています。

ありがとうございました :)

4

1 に答える 1

2

正規表現を構築するときに使用quotemetaしています。これは、すべてのハッシュキーが正規表現で文字通り扱われることを意味します。49103393193[0-9]{1,3}数字の後に 1 ~ 3 桁の数字が続くのではなく、リテラル string を探しています。

を削除map{quotemeta}すれば問題ありません。

注: 入力が信頼できるソースからのものでない場合、入力から正規表現を取得することはセキュリティ ホールです。

更新:forまた、 Perl でC スタイルのループが必要になることはほとんどありません。それらは避けるべきです。その代わり:

foreach my $line (@lines)
{
    #Declare a variable here if you are using it here.
    my @fields = split( /,/, $line );

    $company = $voicePrefix{$1}[1] if ($fields[0] =~ /$voiceRegex/);
}

更新 2:正規表現にアンカーを追加して、長い文字列のサブセットではなく、正確な文字列に一致するようにすることもできます: /^$voiceRegex$/

更新 3:これらの修正により、一致が機能します。ただし、一致した番号を のキーとして使用しようとしているという点で、追加の問題がありますvoicePrefix。ただし、 voicePrefix へのキーは正規表現であり、そのような正規表現に一致する可能性のある数値ではないため、これは機能しません。デザインの変更が必要です。最も簡単な方法は、1 つの大きな正規表現を作成するのではなく、各キーをテストして一致するかどうかを確認することです。

foreach my $line (@lines)
{
    #Declare a variable here if you are using it here.
    my @fields = split( /;/, $line );

    foreach my $regex (keys %voicePrefix)
    {
        $company = $voicePrefix{$regex}[1] if ($fields[0] =~ /$regex/);
    }
}
于 2013-02-20T10:37:31.817 に答える