Header Shadow Image


Perl 5.8 sprintf / printf: Differences in use of regular expressions?

Today I stumbled upon an interesting Perl issue that was causing some random printout in my code then what I expected.  In fact, I’ve used the same sprintf /regular expression in another part  following the script I was writing but it seamed to work just fine there.  The issue was that the script printed two different results when using ’sprintf’ and ‘printf’.  Strangely enough, ’sprintf’ or ‘printf’ printed every second match that it found!  Here is what the test code to resolve this oddity looked like this:

[ BLOCK 1 ]
my $var = sprintf “%s”, $1 if $varT =~ /abc/def/sg
print “|VAR|$var|\n”;

[ BLOCK 2 ]
printf “%s”, $1 if $varT =~ /abc/def/sg

Oddly enough, ‘sprintf‘ didnt’ print anything into ‘$var‘.  ‘printf’ printed to the screen without issues.  This was baffling but the results were always consistent.  Everything was the same except one statement used: ’sprintf’ and the other block used ‘printf’.  I decided then to try and test the regular expression seeing how I found little or no information on differences in either of the functions that would tell me what’s going on.  I then modified the above code to this:

[ BLOCK 1 ]
my $var = sprintf “%s”, $1 if $varT =~ /abc/def/s
print “|VAR|$var|\n”;

[ BLOCK 2 ]
printf “%s”, $1 if $varT =~ /abc/def/sg

I removed the ‘g’ from the ’sprintf’ statement above.  This time the opposite happened.  The ’sprintf’ statement combination above worked and results were printed from ‘$var’ the ‘printf’ statement didn’t do anything this time.  It looked to me that some flag in code used between ‘printf’ and ’sprintf’ was getting toggled when using ‘g’ flag.  In a way, using ’sg’ is redundant.  ’s’ treats a glob of text as a single statement.  ‘\n’ are just a character when using ’s’.  Nontheless ‘g’ as far as I knew shouldn’t cause this sort of behaviour since to me it meant global: from start to finish for all occurances OR Global match for ALL occurances of specified pattern.

In the end, I removed ‘g’ from both statements.  This allowed both statements to print without issues.  I’m still wondering why the ‘g’ modifier causes the above behaviour.  Also pattern ‘abc’ matches only once in a long 20Kb string.

This was for perl 5.8.  It looks to me like an internal flag isn't getting set or reset correctly, hence the issue. 

Leave a Reply

 


     
  Copyright © 2003 - 2013 Tom Kacperski (microdevsys.com). All rights reserved.

Creative Commons License
This work is licensed under a Creative Commons Attribution 3.0 Unported License