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在构建正则表达式时正在使用,这意味着您的所有哈希键都将在正则表达式中逐字处理。您正在寻找文字 string 49103393193[0-9]{1,3},而不是后跟 1-3 位数字的数字。

删除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 的键是正则表达式,而不是可能匹配此类正则表达式的数字。需要更改您的设计。最简单的方法是不创建一个大的正则表达式,而只是测试每个键以查看是否匹配:

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 回答