Les expressions régulières récursives peuvent le faire!
Algorithme tellement simple et évident pour détecter une chaîne contenant un palindrome:
(\w)(?:(?R)|\w?)\1
Sur rexegg.com/regex-recursion, le tutoriel explique comment cela fonctionne.
Cela fonctionne bien avec n'importe quel langage, voici un exemple adapté de la même source (lien) que la preuve de concept, en utilisant 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";
}
les sorties
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
Comparant
L'expression régulière ^((\w)(?:(?1)|\w?)\2)$
fait le même travail, mais comme oui / non à la place "contient".
PS: il utilise une définition où "o" n'est pas un palimbrome, le format avec tiret "able-elba" n'est pas un palindrome, mais "ableelba" l'est. Nommer sa définition 1 .
Quand "o" et "able-elba" sont des palindrones, nommer definition2 .
Comparaison avec une autre "regexe palindrome",
^((.)(?:(?1)|.?)\2)$
la base-regex ci-dessus sans \w
restriction, acceptant "capable-elba".
^((.)(?1)?\2|.)$
( @LilDevil ) Utilise definition2 (accepte "o" et "able-elba" donc différant aussi dans la reconnaissance des chaînes "aaaaa" et "bbbb").
^((.)(?1)\2|.?)$
( @Markus ) non détecté "kook" ni "bbbb"
^((.)(?1)*\2|.?)$
( @Csaba ) Utilisez definition2 .
REMARQUE: pour comparer, vous pouvez ajouter plus de mots à $subjects
et une ligne pour chaque expression régulière comparée,
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";