Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:
Say, a string has embedded palindromes (PD); a PD in this case has odd (at least 3) number of letters. I want a piece of code to be executed exactly once for every PD including nested ones. Let "piece of code" be 'say'. Regex to extract a PD is well-known, and of course TIMTOWTDI, the question is not how to better solve the task.
Almost accidentally I found a solution, which I'm puzzled about. I don't know if it could be a simpler SSCCE without recursion.say 'match' if 'abABCDCBAdeXYZYXfg' =~ / (?>^.*?) ( ( (.)(?-3)\g-1 | (.).\g-1 ) (?{ say $2 }) ) /x;
Output:
YZY XYZYX CDC BCDCB ABCDCBA
Bingo, just what I need. Match fails -- it's irrelevant. But HOW? If either of the following is removed: (1) "^" anchor; (2) independence (s/>/:/), or (3) entire 1st pair of parens, then there are multiple visits to each PD i.e. not what I want. In fact, for (3) the PD groups are also visited in reversed order, this I don't understand neither. And why both PD groups (not only 1st one) are visited.
Being greedy (s/\*\?/*/) produces no output, this I understand (I hope).
If, in case of code above i.e. without removing anything, the engine gives characters back one by one (I thought this is how backtracking works) before it ultimately fails when it (suddenly, somehow) remembers about independence, then I'd expect YZY is found and said; and then XYZYX is found and embedded code executed for both YZY and XYZYX, i.e. both are said (i.e. YZY said twice in total).
P.S. I've seen "Embedded Code Execution Frequency" section in perlre.
|
---|