views:

149

answers:

5

I have the following code:

#$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 this works fine but for some reason the output is "public_html 1" instead of "public_html/foo/bar/foobar.html".

Can anyone see why?

A: 

How about

$webpage =~ s/^$domain//g;
my $linkFromRoot = $dbh->quote($root . $webpage);
S.Mark
+10  A: 

You are not getting the correct answer because the substitution returns you 1 which is the number of items substituted. See perlfaq4's answer to How can I count the number of occurrences of a substring within a string?

$domain = "domainname.co.uk";
$root = "public_html";
$webpage = "domainname.co.uk/foo/bar/foobar.html";
my $string = ($webpage =~ s/^$domain//g);
print $string."\n";

Remove the $string and just do $webpage =~ s/^$domain//g; and then do the string concatenation with $webpage.

ghostdog74
+7  A: 

I think you are assuming that the parentheses around the regular expression induce a list context on it. That it not the case. The left of the assignment operator determines the context, and it is scalar. In scalar context, s/// returns the number of successful substitutions. Putting parentheses around the declared variable variable makes it do what you want it to do, because it makes for a list context.

This:

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

Would return the matches part of $webpage: the domain name. This is probably not what you want. You either want S.Mark's code:

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

Or this

my ($string) = $webpage =~ /^$domain(.+)$//;
my $linkFromRoot = $dbh->quote($root . $string);
Leon Timmermans
I like that you explained the possible mistake in understanding context. It's too important a topic in Perl to miss a chance to reinforce it.
HerbN
+4  A: 

Completely off the topic of your original question, but is it possible that what you actually wanted was:

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

If you don't need another variable, I think the answers above are better, but one of my favorite little syntax tricks is to take advantage of the fact that assignment is an lvalue, so with a little rearrangement of the parenthesis:

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

you can make a copy and modify it in one statement.

Also, along with the other stuff that's a bit weird about this code, there's not much point to that /g on a pattern starting with ^. It can't match more than once.

masto