On Fri, Jun 11, 2004 at 09:10:48AM +0200, Graf Laszlo wrote:
> Hi Ziggy
> 
> You got me wrong. Anyway thanks for example.
> Take a look here:
> 
> #!/usr/bin/perl
> @str = ();
> push @str, "<sm:a>\n";
> push @str, "<sm:b>\n";
> push @str, "BBB\n";
> push @str, "</sm:b>\n";
> push @str, "<sm:cs>\n";            #<----- watch this line
> push @str, "<sm:c no=\"1\">\n";
> push @str, "CCC1\n";
> push @str, "</sm:c>\n";
> push @str, "<sm:c no=\"2\">\n";
> push @str, "CCC2\n";
> push @str, "</sm:c>\n";
> push @str, "</sm:cs>\n";           #<----- and this line
> push @str, "</sm:a>\n";            #<----- and this line
> 
> my $i = 1;
> for (@str) {
>       if ( /^(.*?)(<sm:.+?>)(.*?)$/ .. /^(.*?)(<\/sm:.+?>)/ ) {
>               print "$_";
>       }
>       $i++;
> }
> 
> wich returns these lines:
> 
> <sm:a>
> <sm:b>
> BBB
> </sm:b>
> <sm:cs>                  <----- the first watched line is present
> <sm:c no="1">
> CCC1
> </sm:c>
> <sm:c no="2">
> CCC2
> </sm:c>
>                          <----- the last two are missing from the end
> 
> What is wrong in regexp ?
> 
> Graf  Laszlo

Hi Graf,

You've got an interesting and fairly subtle problem here.  The problem
is not actually with your regex, it's with the .. operator that you
are using to control your 'if' statement.  First, read this:
    http://perldoc.com/perl5.8.4/pod/perlop.html
    (Search for:   In scalar context, ".." returns a boolean value.)

So, let's walk through it (what I am showing here is slightly
inaccurate, as I detail below, but it's easier to understand this
way): 

push @str, "<sm:a>\n";          # Left side turns on; .. == true
ush @str, "<sm:b>\n";           # Still true
push @str, "BBB\n";             # Still true
push @str, "</sm:b>\n";         # **) Right side fires; .. == false
push @str, "<sm:cs>\n";         # Left side turns on; .. == true
push @str, "<sm:c no=\"1\">\n"; # Still true
push @str, "CCC1\n";            # Still true
push @str, "</sm:c>\n";         # **) Right side fires; .. == false
push @str, "<sm:c no=\"2\">\n"; # Left side turns on; .. == true
push @str, "CCC2\n";            # Still true
push @str, "</sm:c>\n";         # **) Right side fires; .. == false
push @str, "</sm:cs>\n";        # Still false
push @str, "</sm:a>\n";         # Still false

Ok, so you see why anywhere that .. is true, that line will be
printed and when it is false, that line will not be printed.  That
should explain everything except the three lines marked **--which, not
coincidentally, are the lines where the right side of the .. fired.  

Here's the reason (quoted from perldoc "It [the .. operator] doesn't
become false till the next time the range operator is evaluated."  So,
basically, when the right side initially fires, the range operator
returns TRUE, but then changes its state to FALSE immediately
thereafter (which is the slight inaccuracy I mentioned above; the
change doesn't happen on the marked lines, it happens on the lines
following). 


Hope that makes sense.

--Dks


-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
<http://learn.perl.org/> <http://learn.perl.org/first-response>


Reply via email to