Beefy Boxes and Bandwidth Generously Provided by pair Networks
Come for the quick hacks, stay for the epiphanies.
 
PerlMonks  

output differs in perl version

by sarvan (Sexton)
on Jul 04, 2011 at 07:46 UTC ( [id://912602]=perlquestion: print w/replies, xml ) Need Help??

sarvan has asked for the wisdom of the Perl Monks concerning the following question:

hi there,
use warnings; use strict; my $str1 = q/It is a guide to action which ensures that the military a +lways obey the commands of the party./; my $str2 = q/It is a guide to action that ensures that the military wi +ll forever heed Party commands is a guide./; my $n = 0; while ( $str1 =~ /(?=(\S+\s+\S+\s+\S+))/g ) { my $t1 = $1; print "$t1\n"; $n++; } print "No of matching is : $n\n";
output:
It is a is a guide a guide to guide to action to action which action which ensures which ensures that ensures that the that the military the military always military always obey always obey the obey the commands the commands of commands of the of the party.

This code works in perl 5.10.1.. but not in perl 5.8.8.. I do have only 5.8.8. I cant upgrade it to latest version, since i m running under my college server. So, Any suggestion or modifications to achieve the same output in 5.8.8..

Thanks..

Replies are listed 'Best First'.
Re: output differs in perl version
by moritz (Cardinal) on Jul 04, 2011 at 08:02 UTC
    This code works in perl 5.10.1.. but not in perl 5.8.8

    How does it fail with 5.8.8?

    I cant upgrade it to latest version, since i m running under my college server.

    Yes you can(*), with App::perlbrew. It lets you easily build and install a perl in your home directory.

    (*) unless your home directory does not allow exectuable files, but that's only rarely the case.

Re: output differs in perl version
by Corion (Patriarch) on Jul 04, 2011 at 08:04 UTC
Re: output differs in perl version
by graff (Chancellor) on Jul 04, 2011 at 09:00 UTC
    I happen to have access to an old freebsd machine that still runs 5.8.8 (hasn't been updated in ages...) and I see that the output looks like stuff that you've shown in earlier posts on this same general topic:

    Well, because I first learned about the (?=...) regex construct (referred to as a "positive look-ahead assertion") when using 5.8.8, I have to assume there's something tricky and unexpected that happens when the look-ahead expression can match variable-length strings (and this was apparently fixed in 5.10).

    If you really have to construct word trigrams in 5.8.8, I guess you'll have to do something other than a pure regex solution relying that sort of syntax. The easier way to do word n-grams is to use split:

    my $str1 = q/It is a guide to action which ensures that the military a +lways obey the commands of the party./; my $str2 = q/It is a guide to action that ensures that the military wi +ll forever heed Party commands is a guide./; for my $str ( $str1, $str2 ) { print "=== input is [$str] ===\n"; my @words = split / /, $str; while ( @words >= 3 ) { print join( " ", @words[0..2] ), "\n"; shift @words; } print "\n"; }
    Of course, if that doesn't satisfy the contrived conditions of a given homework assignment ("You must not use 'split'! And you must use Perl 5.8.8!!"), well, that's a shame. The instructor ought to know better (or shouldn't be so deliberately mean to the poor students...)
      But you always can implement the algorithm in a way that does work in 5.8.8. For example like this:
      while ( $str1 =~ /^(\S+\s+)(\S+\s+\S+)(.*)$/ ) { print "$1$2\n"; $str1 = "$2$3"; $n++; }

      Alternatively, you could use $' (${^POSTMATCH} doesn't work in 5.8.8):
      while ( $str1 =~ /^(\S+\s+)(\S+\s+\S+)/ ) { print "$1$2\n"; $str1 = "$2$'"; $n++; }

        Doesn't work.
Re: output differs in perl version
by Anonymous Monk on Jul 04, 2011 at 08:38 UTC

    hi there, ... So, Any suggestion or modifications to achieve the same output in 5.8.8..

    See Re^7: count the maximum no.of occurence

    What can you do about it? Don't use the feature that triggers this bug in 5.8.8.

Re: output differs in perl version
by AnomalousMonk (Archbishop) on Jul 04, 2011 at 16:48 UTC

    I see letter-by-letter overlapping with the code of the OP when run under ActiveState 5.8.9, and I assume this is the way the code 'doesn't work' under sarvan's 5.8.8. (As others have commented, it would be nice if sarvan would actually say how the code 'doesn't work'.)

    The following modification produces the same output in AS 5.8.9 and Strawberries 5.10.1.5 and 5.12.3.0 (don't ask me just why; the answer is presumably in one of the perldelta docs):

    >perl -wMstrict -le "my $str1 = q/It is a guide to action which ensures that the / . q/military always obey the commands of the party./ ; ;; my $n = 0; while ($str1 =~ m{ (?= (\b \S+ \s+ \S+ \s+ \S+ \b)) }xmsg) { my $t1 = $1; print qq{$t1}; $n++; } ;; print qq{No of matching is: $n}; " It is a is a guide a guide to guide to action to action which action which ensures which ensures that ensures that the that the military the military always military always obey always obey the obey the commands the commands of commands of the of the party No of matching is: 16

    Note: The 5.10+ versions don't need the  \b assertions to produce the same result.

    Update: Actually, the second  \b assertion in the regex above is redundant. The regex
        m{ (?= (\b \S+ \s+ \S+ \s+ \S+)) }xmsg
    gives the output of the OP (which I think is what sarvan wants) under all Perl versions listed above.

Re: output differs in perl version
by ambrus (Abbot) on Jul 04, 2011 at 21:55 UTC

    According to my tests, perl 5.12.3 gives the following incorrect output (same as in your post):

    It is a is a guide a guide to guide to action to action which action which ensures which ensures that ensures that the that the military the military always military always obey always obey the obey the commands the commands of commands of the of the party.

    However, perl 5.14.0 gives the correct output:

    It is a t is a is a guide s a guide a guide to guide to action uide to action ide to action de to action e to action to action which o action which action which ensures ction which ensures ...

    Does someone have a perl 5.12.4 handy to test whether this bug is still present in the 5.12 branch?

      Installed ActivePerl 5.12.4. It's buggy, emitting the same as 5.12.3.

      Yeah, the bug is in the Perls after 5.8.8 not in 5.8.8. If the original output is what is desired, then simply add \b near the front of the regex. That should work in versions even that don't have that bug.

      - tye        

Re: output differs in perl version
by ikegami (Patriarch) on Jul 05, 2011 at 01:46 UTC

    I cant upgrade it to latest version, since i m running under my college server.

    Surely not true. One doesn't need any special permissions to install Perl. It's even easy using App::perlbrew.

    Any suggestion or modifications to achieve the same output in 5.8.8.

    my $n = 0; while ( $str1 =~ /(\S+\s+)(?=(\S+\s+\S+))/g ) { print "$t1$t2\n"; ++$n; }
    or
    my @words = split ' ', $str; my $n = @words - 2; print "@words[$_+0, $_+1, $_+2]\n" for 0..$n-1;

    This code works in perl 5.10.1.. but not in perl 5.8.8.

    Although 5.8.8 is not giving the output you want, it's the one giving the correct output for the given code.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://912602]
Approved by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others perusing the Monastery: (3)
As of 2024-04-19 05:33 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found