Like perlop#m/PATTERN/msixpodualgc (
perlop#m// ), says, m// in scalar context returns true if it succeeds, false if it fails.
Each time m// succeeds against a variable, like when $n = m/twinkle/ig; executes, position is changed, so that while(/twinkle/ig) { executes, only the second twinkle is counted.
If you add this to your program before the while loop
print "pos is ", pos, ", remainder '", substr($_, pos), "'\n";
pos($_) = undef;
this resets pos associated with $_, and then your program will produce
Number of occurences = 1
pos is 7, remainder ' twinkle little star'
Found 2 times
Like perlfaq4 says, if you want the number of occurances, use the flying lentil operator, use
my $count =()= m/twinkle/ig; | [reply] [Watch: Dir/Any] [d/l] [select] |
Consider this:
- You have a deck of cards (52).
- You remove the top card.
- You deal the remaining cards among 4 players.
- You end up one short.
- Now, you collect all cards again.
- This time, you don't remove the top card.
- You deal the remaining card among the 4 players.
Do you now wonder how it comes that if you don't remove the top card, you can deal 52 cards evenly, but you cannot if you do?
That's the same what's happening here. There are 2 matches of twinkle in your string. If you first match one, then the rest, the "rest" only matches once. If you only match "the rest", you get both matches. | [reply] [Watch: Dir/Any] |
Here is the "canonical" way of counting matches into a scalar:
~$ perl -e 'my $x=()="Twinkle twinkle little star"=~/twinkle/ig; print
+ qq|$x\n|'
2
Note the use of () as an intermediate to switch between scalar and list contexts.
I Sympathize because I too had trouble wrapping my head around this.
All great truths begin as blasphemies.
― George Bernard Shaw, writer, Nobel laureate (1856-1950)
| [reply] [Watch: Dir/Any] [d/l] |
To expand upon the AnonMonk's suggestion.
Maybe this helps to show what is going on?
#!/usr/bin/perl -w
use strict;
my $string = "Twinkle twinkle little star";
my @matches = $string =~ m/twinkle/ig;
print "Matches are: @matches\n"; # Matches are: Twinkle twinkle
print "Number of matches: ",scalar @matches,"\n";
print "\n";
# this is the same without creating @matches
# the () is a list and $n here is number of things
# in that list
#
# Without the intervening ()=, to force list context,
# you just get the "truthfulness" (0,1) of the match
# with this, you get the number of things in the list
# without having to create a named array (@matches)
my $n = () = $string =~ m/twinkle/ig;
print "Number of occurences = $n\n";
__END__
Matches are: Twinkle twinkle
Number of matches: 2
Number of occurences = 2
PS: I try to avoid assigning to $_ when possible (and sometimes this is necessary), but I figure that $_ "belongs to Perl". The expression:
foreach ($string)
{
s/^\s*//; #delete leading spaces
s/\s*$//; #delete trailing spaces
}
is seen often and has this effect of assigning $string to $_. $string gets modified due to "aliasing". | [reply] [Watch: Dir/Any] [d/l] [select] |
$_ = "Twinkle twinkle little star";
$n = m/twinkle/i;
print "Number of occurences = $n\n";
while(/twinkle/ig) {
$count++;
}
print "Found $count times\n";
i am still searching why your code is not working!!!
q | [reply] [Watch: Dir/Any] [d/l] |