JM> Dale Henderson said:
The following makes no such assumption:
my $project = $string =~ /Project: ([^,]+),/;
JM> Nitpicking: That's not what Mav wrote and it's not even
JM> correct:
What isn't what Mav wrote?
As to the correctness, I know better than to post untested code.
The correct version is:
my ($project) = $string =~ /Project: ([^,]+),/;
JM> my $project;
JM> ($project = $string) =~s/.*Project
[^,]+),.*/$1/;
JM> At least with Perl v5.8.1 without the parentheses around the
JM> assignment, the value of $project is 1
Yes. the problem is without the parenthesis, the replacement is
being evaluated in scalar context and returning the number of
matches. Not the first match which is what you want.
An equivalent way to do this is:
(my $project = $string) =~ s/.*Project
[^,]+),.*/$1/;
However, this makes $project pointless since the replacement
modifies $string to be the $1 and then $project is assigned the
value of $string.
Note also your solution leaves a leading space returning
" Myproject" not "Myproject" which is what the OP requested but
at the same time requested everything between "Project:" and
",". So we have a specification error. I suspect the OP wanted to
eliminate leading spaces (and possibly trailing ones) which can
be done with
my ($project)=$string=~/Project:\s*([^,]+),/
JM> with the "my", I get "Can't declare scalar assignment in "my"
JM> at - line 2, near ") =~"" without the substitution, I get the
JM> entire string,
That's because your assigning $project to $string and ignoring the
match.
JM> without the .*'s, I get another string.
You need the .*'s to delete the rest of the string. Your
essentially replacing $string with $1.
JM> You can also specify "non-greedyness": ($project = $string) =~
JM> s/.*Project
.*?),.*/$1/;
A negated character class is the "right" answer in this case. For
one reason its more efficient. For a discussion of why you should
choose a negated character class over a non-greedy regex see
"Mastering Regular Expressions" (Owl) 1st edition pgs 226-227.
The way I would normally implement this is something like:
my $project;
if($string=~/Project:\s+([^,]+),/){
$project=$1;
}else{
print "Bad string: $string\n"
}
But this may not be necessary in this case.