# ------------- short summary my $p = 'Terrence and Phillip are sweet'; my ($count,$matchchar,$nummatch,$repchar) = qw(0 e 3 1); my @q = split//,$p; for(@q) { next unless /$matchchar/; $count ++; $_ = $repchar if $count > $nummatch; } print 'out === ',@q # ------------- end short summary. # First you are not using strict which would have pointed # out the fact that you declare a var $rep but use a var called # $repchar and forget to declare $i with my. # #!/usr/bin/perl -w reg.pl # my ($p, @q, $matchchar, $nummatch, $rep, $count, $q, $out); # $p = 'Terrence and Phillip are sweet'; # $count = 0; # $matchchar = "e"; # $nummatch = 3; # $repchar = "1"; # # Bulk my declaration at top kind of looses the scoping value of # my as all these vars are effectively global, although it makes # no difference in your script I like to keep my 'mys' local so # as to speak # $rep is unused, this is supposed to be $repchar but with no # strict you have not allowed perl to tell you. # I have declared and assigned vars almost all at once here # my $p = 'Terrence and Phillip are sweet'; my ($count,$matchchar,$nummatch,$repchar) = qw(0 e 3 1); # # @q = split (/(.*?)/, $p); # # Your split syntax is an odd way to split on null, how about # my @q = split//,$p; # # for($i = 0; $i < $#q + 1; $i++) { # $_ = $q[$i]; # $count += 1 if (/$matchchar/); # if (/$matchchar/ && ($count > $nummatch)) { # $q[$i] = $repchar; # } # } # # You can clean this iteration up heaps. # You could write # for my $i(0..$#q) { # which would shorten it down and cure the missing my but there # is more. All you need is a # for(@q) { # within this loop each element of the @q array is aliased to the # magical variable $_ If we modify $_ we modify that array element. # Also your logic can be improved as you test for a match to # $matchchar twice wich is unecessary. I use a next unless # construct as it makes it obvious what this loop does - if we do # not /$matchchar/ we do the next iteration, read no further! # So without further ado, let's just do: # for(@q) { next unless /$matchchar/; $count ++; $_ = $repchar if $count > $nummatch; } # # $out = join ("", @q[0 .. $#q]); # print "out === $out"; # # join'',@q is much shorter than join ("", @q[0 .. $#q]) and does # the same but but this is shorter. # print "out ===", join'',@q; # has the same effect as these two lines and skips the unecessary # asignment to $out # As print @foo is the same as print join '', @foo; # we can shorten this further to: # print 'out === ',@q; # # BTW # print "@foo"; # is the same as: # print join $", @foo; # The output record seperator $" is set to ' ' by default, but you # can set it to anything you want. So $"='';print "out === @q"; is # yet another variation. # Here is my version of your code, which is remarkably like the # code I did not post in the first place as the Camel book says # when you think you want to chop a string up into substrings # what you really eant is the \G asertion. =pod #!/usr/bin/perl use strict; my $p = 'Terrence and Phillip are sweet'; my ($count,$matchchar,$nummatch,$repchar) = qw(0 e 3 1); my @q = split//,$p; for(@q) { next unless /$matchchar/; $count ++; $_ = $repchar if $count > $nummatch; } print 'out === ',@q; =cut