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

Update: I think, I got this figured out before anybody saw it. lol


I have a little exercise which might sound like homework, but I promise you it isn't! Lol And I almost got it to work, but I can't figure out how to make the last function do what it's supposed to. Update: *Got it!

So, I wanted to write four functions--one that doubles certain characters in a string and another sub that removes double characters from a string. I think I want to clarify that what I want is not this:

$S =~ tr| ||s;

I know, this would collapse multiple spaces to a single space, but that's not what I want to do. I want to do this: "AAAAAA" => "AAA" just replace each pair with a single character. OK. So, I already figured out how to do this.

But then I want to write another sub that repeats certain characters N number of times and finally a last one that finds N number of occurrences of certain characters in a string and replaces each group of characters with one character.
Find groups of 3 letter A's and replace them: "AAAAAA" => "AA"

I'm having trouble with this last sub. It just doesn't want to do what I want. Can someone please help me show me how to do this? It's called SingleCharsX()

#!/usr/bin/perl use strict; use warnings; # This should print: "AABBC" print "\n", DoubleChars("ABC", "AB"); # This should print: "LALA LLAALLAAN N" print "\n", SingleChars("LALA LLLAAALLLLAAAAN NN", "LANG"), "\n\n"; # Okay. Now, make it more complicated... foreach (2..7) { print "\n x $_ : |", DoubleCharsX("ABCD", "ABXY", $_), "|"; } print "\n\n"; foreach (2..7) { print "\n x $_ : |", SingleCharsX("LLLLLLLL-AAAAAAAA", "ABX", $_), "|"; } exit; ############################################ ## FUNCTIONS ## ############################################ # This function doubles every instance of a list of characters in # a string and returns a new string. For example, it can be used # to double every instance of space or new line characters. # # DoubleChars("Helo World!", "!lo ") => "Helloo Woorlld!!" # DoubleChars("Helo World!", "HHH") => "HHelo World!" # # Usage: STRING = DoubleChars(STRING, CHARS) # sub DoubleChars { defined $_[0] && length($_[0]) or return ''; defined $_[1] && length($_[1]) or return $_[0]; my $S = $_[0]; $S =~ s/([\Q$_[1]\E]{1})/$1$1/g; return $S; } ############################################ # # This function removes certain characters that appear twice next # to each and leaves only one instance. This can be used to undo # the effects of the DoubleChars() function. # # SingleChars(" HEELLLLLLO OO!", "OL") => " HEELLLO O!" # SingleChars("AABBCAABBC", "AB") => "ABC" # # Usage: STRING = DoubleChars(STRING, CHARS) # sub SingleChars { defined $_[0] && length($_[0]) or return ''; defined $_[1] && length($_[1]) or return $_[0]; my $S = $_[0]; $S =~ s/([\Q$_[1]\E]{1})\1/$1/g; return $S; } ############################################ # This function doubles or triples every instance of # a list of characters in a string and returns a new string. # For example, it can be used to repeat every instance of # the exclamation point. The second argument tells what # to repeat, and the third argument tells how many times # to repeat those characters. # # DoubleCharsX("Hello World!", "!", 3) => "Hello World!!!" # # Usage: STRING = DoubleCharsX(STRING, CHARS, [REP]) # sub DoubleCharsX { defined $_[0] && length($_[0]) or return ''; defined $_[1] && length($_[1]) or return $_[0]; my $REP = defined $_[2] ? int($_[2]) : 2; $REP >= 2 or $REP = 2; my $S = $_[0]; $S =~ s/([\Q$_[1]\E]{1})/$1 x $REP/ge; return $S; } # This function doubles or triples every instance of # a list of characters in a string and returns a new string. # For example, it can be used to repeat every instance of # the exclamation point. The second argument tells what # to repeat, and the third argument tells how many times # to repeat those characters. # # SingleCharsX("Pressss a keeeeyyy!", "ey", 3) => "Pressss a keey!" # # Usage: STRING = SingleCharsX(STRING, CHARS, [REP]) # sub SingleCharsX { defined $_[0] && length($_[0]) or return ''; defined $_[1] && length($_[1]) or return $_[0]; my $REP = defined $_[2] ? int($_[2]) : 2; $REP >= 2 or $REP = 2; my $S = $_[0]; foreach my $CHAR (split(//, $_[1])) { $S =~ s/\Q$CHAR\E{$REP}/\Q$CHAR\E/g; } return $S; }

Update: Also, I am not sure how one should call these subs. I mean DoubleCharsX is not a very creative name. Maybe RepChars() would be better? But then how would I call SingleCharsX() ? The other thing is I don't even know what kind of title to give this thread. I'm not very good at naming these things. :P

Update: I think, everything works fine, it's not that the program doesn't do what it's supposed to, but I was expecting a different output. And since the output didn't match what I imagined it should be, I thought it was an error. I thought it should print something like this:

AABBC LALA LLAALLAAN N x 2 : |AABBCD| x 3 : |AAABBBCD| x 4 : |AAAABBBBCD| x 5 : |AAAAABBBBBCD| x 6 : |AAAAAABBBBBBCD| x 7 : |AAAAAAABBBBBBBCD| x 2 : |LLLLLLLL-AAAAAA| x 3 : |LLLLLLLL-AAAAA| x 4 : |LLLLLLLL-AAAA| x 5 : |LLLLLLLL-AAA| x 6 : |LLLLLLLL-AA| x 7 : |LLLLLLLL-A| AND INSTEAD IT WAS PRINTING THIS: AABBC LALA LLAALLAAN N x 2 : |AABBCD| x 3 : |AAABBBCD| x 4 : |AAAABBBBCD| x 5 : |AAAAABBBBBCD| x 6 : |AAAAAABBBBBBCD| x 7 : |AAAAAAABBBBBBBCD| x 2 : |LLLLLLLL-AAAA| x 3 : |LLLLLLLL-AAAA| x 4 : |LLLLLLLL-AA| x 5 : |LLLLLLLL-AAAA| x 6 : |LLLLLLLL-AAA| x 7 : |LLLLLLLL-AA|