我想用数字键对哈希中的每个键重复一个过程。因此,有 3 种可能性,有 3 个 if,每一种都比较数组索引的值,因此,如果该位置
eq
为“sp”、“sp2”或“sp3”,它将在文档中搜索某个位置值,然后就可以打印了。它不起作用,每次只给我一个值,我想获取与哈希相对应的值。例如,哈希值可以是 %grupos=(1,'A',2,'G',3,'J')
文档.txt是:
HS0.32
CS0,77
CD0.62
CT0,59
C10,77
C20,62
C30,59
OS0.73
OD0,6
O10,73
O20,6
NS0.75
代码是:
@ hibridaciones=("sp","sp2",sp3")
%grupos=(1,'A',2,'G',3,'J')
open (covalencia,"<", "cov.txt") or die "$!\n";
print keys %grupos;
keys %grupos;
foreach my $z (keys %grupos) {
print "\n$z\n";
if (@hibridaciones[my $z-1] eq "sp") {
while (my $line = <covalencia>) {
if ( $line=~/^C1/) {
$line =~s/C1//;
$radio=$line;
print "\n$radio";
}
}
}
if (@hibridaciones[my $z-1] eq "sp2") {
while (my $line = <covalencia>) {
if ($line=~/^C2/) {
$line =~s/C2//;
$radio=$line;
print "\n$radio";
}
}
}
if (@hibridaciones[my $z-1] eq "sp3") {
while (my $line = <covalencia>) {
if ($line=~/^C3/) {
$line =~s/C3//;
$radio=$line;
print "\n$radio";
}
}
}
}
close (covalencia);
您的代码存在许多问题。您似乎不太可能实际运行此代码,因为它已损坏,缺少双引号会破坏代码的其余部分,加上缺少分号,这也会造成严重破坏。
但是你也有一些设计错误,或者糟糕的选择。我将在下面查看您的代码。
首先,始终使用
use strict; use warnings;
。这两个实用指令将防止您犯下难以发现的简单错误。一开始可能会很困难,但是没有它们的编码是非常危险的。
@ hibridaciones=("sp","sp2",sp3")
%grupos=(1,'A',2,'G',3,'J')
缺少两个分号。
@
和数组名称之间的空格很糟糕,但代码仍然有效。但你确实缺少一个双引号 sp3
。
open (covalencia,"<", "cov.txt") or die "$!\n";
以特定模式打开的三个参数很好。但这段代码仍然对裸字发出警告
covalencia
。更好的选择是使用词法变量,例如open my $fh, "<", ...
。变量名 $fh
通常用作文件句柄。
keys %grupos;
这个语句在 void 上下文中没有任何作用。
foreach my $z (keys %grupos) {
你应该使用不言自明的变量名,这会给你省去很多麻烦。所以,你应该在这里使用
my $key
。
if (@hibridaciones[my $z-1] eq "sp") {
这里有很多问题。
@
用于数组切片。如果只有一个元素,则使用 $
。这将触发来自 use warnings
的警告。my $z
将创建一个名为 $z
的新变量。如果您启用了 warnings
,它会警告您。if ( $key == 1 ) { # this is "sp"
。请注意,这里的最后一点使整个
@hibridaciones
数组变得多余。
while (my $line = <covalencia>) {
文件句柄只能使用一次到文件末尾。之后,
<covalencia>
将返回undef
。这意味着以下 while
循环根本不会运行。您应该将文件中的行放入数组中,然后对其进行循环。例如。 for my $line (@lines)
if ( $line=~/^C1/) {
$line =~s/C1//;
虽然技术上没有错误,但在循环变量上使用
s///
会让您面临难以检测错误的风险。当使用 for/foreach
循环时,循环变量是原始变量的别名,因此更改循环变量将更改原始变量。在这种情况下不会发生这种情况,因为您正在读取文件,但由于我的建议是您使用其他解决方案,这将在稍后相关。
我的建议是捕获行尾,这是一个非破坏性的选项:
if ($line =~ /^C1(.*)/)
...然后print $1
。或者使用 say
,它会自动添加换行符(请参阅下面的代码)。
$radio=$line;
print "\n$radio";
$radio
变量是多余的,可以删除。
总而言之,我最终得到的是这样的:
use strict;
use warnings; # never code without strict and warnings enabled
use feature 'say'; # say $1 replaces print "$1\n"
my %grupos = (1,'A',2,'G',3,'J');
open (my $covalencia,"<", "cov.txt") or die "$!\n";
my @lines = <$covalencia>; # your file is now in @lines
close ($covalencia);
foreach my $key (keys %grupos) {
say "----- $key -----";
if ($key == 1) { # "sp"
for my $line (@lines) { # now we can loop as much as we want
if ( $line=~ /^C1(.*)/) { # capture to $1
say $1; # print $1
}
}
} elsif ($key == 2) { # "sp2"
for my $line (@lines) {
if ($line=~ /^C2(.*)/) {
say $1;
}
}
} elsif ($key == 3) { # "sp3"
for my $line (@lines) {
if ($line=~ /^C3(.*)/) {
say $1;
}
}
}
}
给出输出:
----- 1 -----
0,77
----- 3 -----
0,59
----- 2 -----
0,62