Perl 正则表达式使用 qr//

Perl Regex using qr//

我正在制作一个解析文本文件的模块,我尝试匹配的所有内容前面都有一个 #,但是当我尝试使用 qr// 时,它没有'不匹配任何东西。至少对我来说,这里的大问题是我需要它在数组中循环,我认为我不能使用 </code> 或者它不能正常工作。 <code>%$hash_ref 是从数据库中提取的信息,其中键是列,值是值(很明显)。文本文件包含 #C3_WK_PH#SPECIAL_NOTES 等词。

sub replace {   
    open (my $in,  '<', "file.txt")  or die "cannot open $in: $!";
    open (my $out, '>', "file2.txt") or die "cannot open $out: $!";

    while (<$in>)
    {
            my @values = values %$hash_ref;
            my @keys   = keys %$hash_ref;
            my $count  = @keys;

            while ($count > 0) {
                my $thing  = $keys[$count];
                my $regexp = qr/#($thing)/;
                s/$regexp/$values[$count]/g;
                $count = $count - 1;
            }
            print $out $_;
    }
            close $in;
            close $out;
}

我知道我正在解析每一行 $count 次,但这是有意的。

您的问题与qr//无关。 Perl 中的数组是从 0 开始索引的,所以第一次通过 while ($count > 0) ... 循环时:

        my $thing = $keys[$count];

设置$thingundef因为@keys的最大元素是$count-1

        my $regexp = qr/#($thing)/;

$regexp 设置为 qr/#()/,并且

        s/$regexp/$values[$count]/g;

从您的输入中删除所有 # 个字符,将它们替换为空,并使其余的预期替换毫无意义。

如果您使用的是 use warnings,您会得到有关该问题的提示。

将循环编写为 while ($count-- > 0) ... 会起作用(并确保处理 $keys[0]$values[0] 中的值),但请考虑一种更 Perl-y 的迭代方式你的哈希:

foreach my $thing (keys %$hashref) {
    my $replace = $hashref->{$thing};
    ...
}

while (my ($thing,$replace) = each %$hashref) {
    ...
}

这比你得到的稍微简化了一点,但它应该给出正确的想法:

%hash = ( 'f' => 'foo', 'b' => 'bar', 'c' => 'chimp' );
replace();

sub replace {   
    open (my $in, '<', "file.txt") or die "cannot open $in: $!";
    while (<$in>)
    {
            foreach my $thing (keys %hash) {
            s/#($thing)/$hash{$thing}/g;
            #print;
            }
            print;
    }
    close $in;
}

使用该代码,我能够成功地将带有#f、#b 和#c 的文本转换为带有 foo、bar 和 chimp 的文本。

回到散列参考,我有这段代码,它似乎再次工作正常。 (我这次留下了跟踪语句。)

%hash = ( 'f' => 'foo', 'b' => 'bar', 'c' => 'chimp' );
$hash_ref = \%hash;
replace();

sub replace {   
    open (my $in, '<', "file.txt") or die "cannot open $in: $!";
    while (<$in>)
    {
            foreach my $thing (keys %{$hash_ref}) {
            #my $regexp = qr/#($thing)/;
print "REPLACING $thing WITH ${$hash_ref}{$thing}\nBEFORE: $_";
            s/#($thing)/${$hash_ref}{$thing}/g;
print "AFTER: $_";
            }
            print;
    }
    close $in;
}

如果 ${$hash_ref}{$thing} 语法不适合您,那么您需要告诉我们您是如何创建 $hash_ref 的,因为该语法在这里工作正常...: