2010-02-06 73 views
5

我有以下代码:为什么Perl用“1”代替我的字符串?

#$domain = domainname.co.uk 
#$root = public_html 
#$webpage = domainname.co.uk/foo/bar/foobar.html 
my $string = ($webpage =~ s/^$domain//g); 
my $linkFromRoot = $dbh->quote($root . $string); 

Usualy这个工作正常,但由于某种原因,输出为“的public_html 1”而不是“的public_html /富/酒吧/ foobar.html”。

任何人都可以看到为什么?

+5

当您遇到这些问题时,请开始平分您的代码以查找问题数据显示的位置。在这种情况下,在使用它之前检查'$ string'的值,发现它是'1',然后在替换运算符上进行读取以查看它在做什么。 :) – 2010-02-06 11:41:59

+1

题外话,但为什么DBI'报价'而不是占位符? :) – hobbs 2010-02-06 11:47:59

回答

0

如何

$webpage =~ s/^$domain//g; 
my $linkFromRoot = $dbh->quote($root . $webpage); 
7

我想你假设围绕正则表达式的括号会在其上引发一个列表上下文。那它不是的情况。赋值运算符的左边确定上下文,它是标量。在标量上下文中,s ///返回成功替换的数量。将圆括号放在声明的变量变量上会使它做你想做的事情,因为它使得列表上下文成为可能。

此:

my ($string) = $webpage =~ s/^$domain//; 

将返回$网页的匹配部分:域名。这可能不是你想要的。要么你想S.Mark代码:

$webpage =~ s/^$domain//; 
my $linkFromRoot = $dbh->quote($root . $webpage); 

或者这

my ($string) = $webpage =~ /^$domain(.+)$//; 
my $linkFromRoot = $dbh->quote($root . $string); 
+0

我喜欢你在理解上下文中解释可能的错误。 Perl中的一个话题太重要了,因此错过了加强它的机会。 – HerbN 2010-02-06 19:39:24

4

完全离开你原来的问题的话题,但有可能是你真正想要的是:

my $webpage = URI->new("http://domainname.co.uk/foo/bar.html"); 
my $path = $webpage->rel("http://domainname.co.uk/"); 
print "public_html/$path\n"; 
0

如果你不需要另一个变量,我认为上面的答案是更好的,但我最喜欢的一个小句法技巧是利用这个事实,即赋值是一个左值,所以在重新排列括号:

(my $string = $webpage) =~ s/^$domain//g; 

您可以复制并修改它在一个语句中。

此外,还有其他一些对此代码有点奇怪的东西,在^开头的模式上没有多少指向/g。它不能匹配超过一次。

相关问题