递归正则表达式可以做到!
如此简单且不言而喻的算法来检测包含回文的字符串:
(\w)(?:(?R)|\w?)\1
在rexegg.com/regex-recursion,教程解释了它是如何工作的。
它适用于任何语言,这里是一个使用 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";
}
输出
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
比较
正则表达式^((\w)(?:(?1)|\w?)\2)$ 做同样的工作,但作为yes/not 代替“包含”。
PS:它使用的定义是“o”不是回文,“able-elba”连字符格式不是回文,但“ableelba”是。将其命名为 definition1。
当“o”和“able-elba”是回文时,命名为definition2。
与另一个“回文正则表达式”比较,
^((.)(?:(?1)|.?)\2)$ 上面没有\w 限制的base-regex,接受“able-elba”。
^((.)(?1)?\2|.)$ (@LilDevil) 使用 definition2(接受“o”和“able-elba”,因此在识别“aaaaa”和“bbbb”字符串时也存在差异) .
^((.)(?1)\2|.?)$ (@Markus) 未检测到“kook”和“bbbb”
^((.)(?1)*\2|.?)$ (@Csaba) 使用definition2。
注意:要进行比较,您可以在 $subjects 添加更多单词,并为每个比较的正则表达式添加一行,
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";