This single regexp might be what you're after. It uses backreferences to make sure that you match the same thing three or more times, and then keeps only the first two occurrences. All this has to happen at the end of the string.
s/(\w){2}\1+\Z/$1$1/;
Update: Perlbotics solution above is it. ;) Bah, hate it when that happens!
To get a good explanation, run the following one-liner:
perl -MYAPE::Regex::Explain -E 'say YAPE::Regex::Explain->new(qr/(
\w){2}\1+\Z/)->explain();'
Update2:
So since I botched it, and the best s/// construct was already posted, I figured I may as well have a little fun with my walk of shame. :)
The following is a substr approach that is more in keeping with how life was before every programming language developed Perl-envy and incorporated its own version of regular expressions (no, Perl didn't invent them, but was a big part of popularizing them). Have a look and enjoy knowing that you live in a Perlish world instead.
use strict;
use warnings;
use v5.12;
my $string = "abcdefggggggggggg";
my $position = length( $string ) - 1;
my $find = substr $string, $position, 1;
$position-- while substr( $string, $position, 1 ) eq $find;
substr( $string, $position + 3, length( $string ) - ( $position + 3 ),
+ '') if length( $string ) - $position > 3;
say $string;
|