Perl认为所有字符串都是相同的

时间:2013-06-10 17:20:19

标签: perl if-statement substring

编辑:我之前尝试使用eq而不是==,但它没有用。出于某种原因,现在确实如此。此时可能存在另一个错误,导致其无法正常工作,但现在已经解决了。谢谢。

我正在尝试做一些简单的验证。我想确保通过变量提供的重定向网址是否以特定网站开头。如果是,则重定向将通过,否则,重定向将重定向到站点的根目录。看起来很直接,对吧?

$redir = $input{'redirect'};
$redir_sub = substr($redir, 0, 21);
if ($redir_sub == "http://www.mysite.com") {
     print "Location: $redir \n\n";
}else{
     print "Location: http://www.mysite.com \n\n";
}

问题是,无论我在哪里放置变量,“if”都返回true。我可以把我最喜欢的webcomic放在那里,它会重定向到它,尽管字符串不匹配。例如:

$redir = $input{'redirect'};
$redir_sub = "http://www.yahoo.com"
if ($redir_sub == "http://www.mysite.com") {
     print "Location: $redir_sub \n\n";
}else{
     print "Location: http://www.mysite.com \n\n";
}

重定向到雅虎!发生了什么事?

5 个答案:

答案 0 :(得分:2)

运算符==用于比较数字。您应该将其替换为运算符eq

答案 1 :(得分:2)

if ($redir_sub == "http://www.mysite.com")

应该是

if ($redir_sub eq "http://www.mysite.com")

因为eq是字符串相等运算符,并且使用==强制进行数字比较,所以在这种情况下条件总是在0 == 0为真时计算为trues。

答案 2 :(得分:2)

TL; DR:使用eq而非==


Perl作为一种语言似乎有一个问题:它使用相同的数据类型(标量)来处理很多不同的事情,包括字符串和数字。标量同时存在,而不仅仅是其中之一。 Perl没有类型注释,也无法指示变量是否包含字符串或数字。

当我们考虑相等测试时会产生问题。假设有两个标量$a = "42.0"$b = 42。他们是平等的吗?是和否:

  • 字符串"42""42.0" 相同的东西!这些相等。
  • 数字4242.0相等!

如上所述,Perl不使用类型系统来解决这种歧义。相反,它使用不同的运算符集进行字符串和数字运算:

eq ne lt le gt ge cmp
== != <  <= >  >= <=> 

答案 3 :(得分:2)

您的问题是您没有使用

use warnings;

这就是Perl允许你犯这个错误的原因。您正在使用数字相等运算符来比较字符串。因此,Perl首先尝试将每个参数转换为数字。由于您的字符串不是以数字开头(并且看起来不像数字),因此它们会转换为零0。因此你的表达

if ($redir_sub == "http://www.mysite.com")

真的意味着这个

if (0 == 0)

当然,这总是正确的。

如果你一直在使用警告,你会得到错误:

Argument "http..." isn't numeric in numeric eq (==) at ...
Argument "http..." isn't numeric in numeric eq (==) at ...

对于您的问题,您应该使用eq而不是==来比较字符串。

答案 4 :(得分:1)

==进行数值比较。 eq进行字符串比较。当您使用字符串作为数字时,perl会将您的字符串传递给您的c库的aton()。所以你真的问你的计算机是否0 == 0这是真的。