的问题很简单:你在你的程序中使用$1
,$2
,并且$3
,但你使用它们的时候,你已经失去了其价值。这些是全局符号,只要使用正则表达式运算符就会被替换。在第一次正则表达式匹配后,将它们保存在另一个变量中:
$first = $1;
$second = $2;
$third = $3;
您还应该小心正则表达式。你的正则表达式工作,但它们非常非常狭窄。我第一次在文件中加入标签时错过了它。我喜欢使用\s+
来处理任何类型的空白。这将涵盖多个选项卡或空间或不同组合。
我也强烈建议你多学些modern Perl。你会立刻拿起这个问题,如果你已经在你的程序中使用这两条线:
use strict;
use warnings;
的strict
将确保您通过my
或our
定义的变量。这确保你不会说$Foo
一个地方和$foo
另一个地方,并想知道你在$foo
存储的价值发生了什么。
warnings
会立即突出显示$1
和$2
在进行第二次正则表达式匹配时没有值。
由于require
,当您使用strict
时,变量声明中的内容有点粘稠。 A my
变量是一个范围有限的严格局部变量。这就是为什么99%的时间使用它。
A my
变量只存在于其声明的范围内。例如,如果你声明了一个循环内的变量,它不会在循环外存在:
if ($a > $b) {
my $highest = $a;
}
else {
my $highest = $b;
}
print "The highest value is $highest\n";
因为$highest
是if语句里面定义这是行不通的。你必须申报$highest
的声明外,它的工作:
my $highest;
if ($a > $b) {
$highest = $a;
}
else {
$highest = $b;
}
print "The highest value is $highest\n";
的our
声明的变量是全局可用整个包。你可以在任何地方定义它 - 在一个循环内部,在一个if语句中,在任何地方 - 它将在稍后提供。
包只是一个名称空间。除非您另行声明,否则您始终处于main
包中。防止模块变量影响代码中的变量很有用。这样,您包含的模块可以使用变量$foo
,并且您可以使用变量$foo
而不会相互干扰。
我不得不这样做的原因是因为你的require
。 A my
变量仅在其范围内可用。也就是说,for循环,if语句或整个文件。注意上一个:整个文件。这意味着如果我做my %h1
,它不会存在于文件之外。因此,我必须声明一个our
。
此外,当您使用strict
时,它是相当严格的。它在发现一个尚未声明的变量时会产生编译时错误。因此,我不得不在主程序中声明%h1
,所以编译器知道它。
我也使用say
声明,我从我的use feature qw(say);
得到。这就像print
,除了它总是打印一个NL字符。它看起来并不多,但在许多情况下它可能不那么杂乱。
现在强烈建议您使用声明的标量来打开文件而不是文件句柄。文件句柄是全局的,可能会导致问题。另外,在子程序中很难使用文件句柄。另外,建议使用三部分公开声明。当文件名以>
或|
开头时,这可以防止出现问题。
这里的程序改写了一些更现代的Perl天赋。我保留了标准算法,但添加了新的编译指示,在require
之前声明%h1
,并使用更标准的open
。否则,这几乎是你所拥有的。
#! /usr/bin/env perl
#
use strict;
use warnings;
use feature qw(say);
our %h1;
require "hash.pl";
open (my $input_fh, "<", "input.txt")
or die "can't open file: $! \n";
foreach my $amp (<$input_fh>) {
chomp $amp;
if ($amp =~ /(\d+)\s+(\d+)\s+(\d+)/) {
# Got to save the $1, $2, and $3 for later
my $first = $1;
my $second = $2;
my $third = $3;
foreach my $key (keys %h1) {
foreach my $tmp1 (@{$h1{$key}}) {
if ($tmp1 =~ /($first\s+$second|$second\s+$first)/) {
say qq("$key": "$third");
}
}
}
}
}
close $input_fh;
问题是什么? – ArjunShankar