Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW
 
PerlMonks  

Re: Try this in Regexp palindrome

by bart (Canon)
on Mar 21, 2005 at 11:13 UTC ( [id://441176]=note: print w/replies, xml ) Need Help??


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.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others chilling in the Monastery: (4)
As of 2024-04-24 19:38 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found