即使它们相等,perl等于字符串也返回0

时间:2011-05-17 23:33:42

标签: perl string comparison

Perl继续让我感到惊讶。我有一个代码从命令行获取输入并检查它是否在文件中。我有这样一个文件:

LS

日期

PWD

触摸

RM

首先我把这个文件读成

open(MYDATA,"filename") or die "Can not open file\n";
@commandlist = <MYDATA>;
chomp @commandlist;
close MYDATA;

参数在$ commandname变量中。为了检查它是否正确,我打印到屏幕上。

print $commandname."\n";

效果很好。然后我写了代码。

$count = @commandlist;
for($i=0;$i < $count;$i++)
{
    print $commandname;
    print $commandlist[$i];
    print "\n";
    if($commandname eq $commandlist[$i])
    {
        print "equal\n";
    }
}

并且它不打印'相等'。但它应该这样做,因为$ commandname变量具有文件中的值'ls'。我还打印$ commandname和$ commandlist [$ i]的值,看看它们是否“相等”,我得到了输出:

ls
lsls
lsdate
lspwd
lstouch
lsrm

在这里我看到他们得到了相同的值,但为什么永远不会将eq运算符计算为零。 另外为了完成这项任务,我尝试了各种方法,所有这些方法都变得毫无用处,比如从数组中创建哈希并使用exists。 我一天都在努力寻找这个看似简单的问题,但我只是不明白。 提前致谢

编辑: 当我改变上面的循环如下

$count = @commandlist;
for($i=0;$i < $count;$i++)
{
    print $commandlist[$i];
    print $commandname;
    print "\n";
    if($commandname eq $commandlist[$i])
    {
        print "equal\n";
    }
}

我的输出就像。

ls
ls
lste
lsd
lsuch
ls

似乎由于某种原因它会覆盖一些角色。

编辑:

我的整个脚本就像:

#reading file code, i posted above
while(<>)
chomp($_);
$commandname = $_;
if($commandname eq "start"){
##something here
} elsif ($commandname eq "machines"){
##something here
} else {

    $count = @commandlist;
    for($i=0;$i < $count;$i++)
    {
        print $commandlist[$i];
        print $commandname;
        print "\n";
        if($commandname eq $commandlist[$i])
        {
            print "equal\n";
        }
    }

}

3 个答案:

答案 0 :(得分:3)

代码中的一点改变会导致你正在寻找的东西,在你把它用于比较之前,从数组中“扼杀”字符串。这是

chomp $commandlist[$i];

if($commandname eq $commandlist[$i])
{
    print "equal\n";
}

编辑:根据perldoc chomp,当你选择一个列表时,你应该括号。所以,在你的情况下......而不是简单地说

chomp @commandlist 

使其像

chomp(@commandlist)

最终编辑:我试过这个并且工作正常。试一试

$commandname = $ARGV[0];

open(MYDATA,"chk.txt") or die "Can not open file\n"; 
@commandlist = <MYDATA>; 
chomp(@commandlist);
close MYDATA; 

print $commandname."\n"; 

$count = @commandlist;
print $commandname; 
for($i=0;$i < $count;$i++) 
 {

 print $commandlist[$i]; 
 print "\n"; 
 if($commandname eq $commandlist[$i]) 
 {   
  print "equal\n";   
 } 
 }

答案 1 :(得分:3)

重写表示存在CR。这些行以CR LF结尾,但您只能使用LF删除chomp。变化

while (<>) {
    chomp($_)

while (<>) {
    s/\s+\z//;

答案 2 :(得分:1)

您可以考虑将代码重构为:

my $path='filename';
my $match='ls';

第1部分 - 阅读文件

open(my $fh, '<', $path) or die "failed to open $path: $!";
my @commandlist=<$fh>;
chomp @commandlist;  
# or you can combine these lines as: 
#    chomp(my @commandlist=<$fh>);
# because chomp operates on the array itself rather than making a copy.
close($fh);

use File::Slurp qw/ read_file /; 
# see http://search.cpan.org/dist/File-Slurp/lib/File/Slurp.pm

my @commandlist=read_file($path);  # result is pre-chomped!

第2部分 - 检查比赛

foreach my $command (@commandlist) {
  print "$match equals $command\n" if $match eq $command;
}

一个重要的考虑因素是文件中的每一行必须只包含 命令名称,并且不能以任何空格或制表符开头或结尾。要补偿可能的前导或尾随空格,请尝试:

foreach my $command (@commandlist) {
  $command=~s/^\s+|\s+$//g; # strip leading or trailing whitespace
  print "$match equals $command\n" if $match eq $command;
}

最后,总是用Perl开发人员最好的朋友开始你的Perl脚本:

use strict;
use warnings;

将捕获由草率编程实践引起的大多数(如果不是全部)错误。 (我们都受此影响!)