Rekursive reguläre Ausdrücke können es tun!
So einfacher und selbstverständlicher Algorithmus, um eine Zeichenfolge zu erkennen, die ein Palindrom enthält:
(\w)(?:(?R)|\w?)\1
Unter rexegg.com/regex-recursion erklärt das Tutorial, wie es funktioniert.
Es funktioniert gut mit jeder Sprache, hier ein Beispiel aus derselben Quelle (Link) wie Proof-of-Concept mit PHP:
$subjects=['dont','o','oo','kook','book','paper','kayak','okonoko','aaaaa','bbbb'];
$pattern='/(\w)(?:(?R)|\w?)\1/';
foreach ($subjects as $sub) {
echo $sub." ".str_repeat('-',15-strlen($sub))."-> ";
if (preg_match($pattern,$sub,$m))
echo $m[0].(($m[0]==$sub)? "! a palindrome!\n": "\n");
else
echo "sorry, no match\n";
}
Ausgänge
dont ------------> sorry, no match
o ---------------> sorry, no match
oo --------------> oo! a palindrome!
kook ------------> kook! a palindrome!
book ------------> oo
paper -----------> pap
kayak -----------> kayak! a palindrome!
okonoko ---------> okonoko! a palindrome!
aaaaa -----------> aaaaa! a palindrome!
bbbb ------------> bbb
Vergleichen
Der reguläre Ausdruck ^((\w)(?:(?1)|\w?)\2)$
erledigt den gleichen Job, aber als yes / not "enthält".
PS: Es wird eine Definition verwendet, bei der "o" kein Palimrom ist, das Bindestrich-Format "able-elba" kein Palindrom ist, "ableelba" jedoch. Benennung es definition1 .
Wenn "o" und "able-elba" Palindronen sind, benennen Sie definition2 .
Vergleich mit anderen "Palindrom-Regexen",
^((.)(?:(?1)|.?)\2)$
die Basis-Regex oben ohne \w
Einschränkung, akzeptiert "able-elba".
^((.)(?1)?\2|.)$
( @LilDevil ) Verwenden Sie definition2 (akzeptiert "o" und "able-elba", die sich auch in der Erkennung von "aaaaa" - und "bbbb" -Strings unterscheiden).
^((.)(?1)\2|.?)$
( @Markus ) weder "kook" noch "bbbb" erkannt
^((.)(?1)*\2|.?)$
( @Csaba ) Verwenden Sie definition2 .
HINWEIS: Zum Vergleichen können Sie $subjects
für jeden verglichenen regulären Ausdruck mehr Wörter und eine Zeile hinzufügen.
if (preg_match('/^((.)(?:(?1)|.?)\2)$/',$sub)) echo " ...reg_base($sub)!\n";
if (preg_match('/^((.)(?1)?\2|.)$/',$sub)) echo " ...reg2($sub)!\n";
if (preg_match('/^((.)(?1)\2|.?)$/',$sub)) echo " ...reg3($sub)!\n";
if (preg_match('/^((.)(?1)*\2|.?)$/',$sub)) echo " ...reg4($sub)!\n";