in reply to Try this in Regexp palindrome

Using a delayed execution assertion, typically used to create recursively matching regexes, I came up with this:
my $re; $re = qr/((.)(??{ $re })\2|.)/; my $s = 'abcdegedfc'; foreach my $i (0 .. length($s) - 1) { local $\ = "\n"; # add newline to print substr($s, $i) =~ /^$re/ and print $1; }
I need a loop, because the regex by itself doesn't search for the longest palindrome, so I added a /^/ anchor to avoid any potential, useless backtacking. It doesn't actually chnage the result.

This little program prints:

a
b
c
deged
ege
g
e
d
f
c
So all you still have to do, is keep the longest match from the loops.

update: I found a second working regex, inspired by holli who came up with the idea to use reverse:

my $s = 'abcdegedfc'; foreach my $i (0 .. length($s) - 1) { local $\ = "\n"; # add newline to print substr($s, $i) =~ /((.*).?(??{ quotemeta reverse $2 }))/ and print $1; }
Output is identical to the previous program.

Replies are listed 'Best First'.
Re^2: Try this in Regexp palindrome
by Roy Johnson (Monsignor) on Mar 21, 2005 at 14:18 UTC
    Your delayed-evaluation expression isn't quite right. It won't match palindromes like 'feef' that don't have a central character. You need to make the single dot optional. And if you put the alternation in the middle, you won't match one-character "palindromes".

    You can also simplify your search by putting the pattern in a lookahead and doing a while-global match:

    $_ = 'abcdegedfc'; # Try it without the g, too. my $re; $re = qr/((.)(?:(??{$re})|.?)\2)/; print "$1\n" while (/(?=$re)/g);
    If you change the * to a + in the reverse version, you exclude single-character palindromes. The lookahead while-global trick helps here, too:
    $_ = 'abcdegedfc'; print "$1\n" while (/(?=((.+).?(??{quotemeta reverse $2})))/g);

    Caution: Contents may have been coded under pressure.
      Your delayed-evaluation expression isn't quite right. It won't match palindromes like 'feef' that don't have a central character. You need to make the single dot optional.
      You're right. I knew that, and I still forgot about it. Thanks for the correction.