Yinelemeli Normal İfadeler bunu yapabilir!
Palindrom içeren bir dizeyi tespit etmek için çok basit ve apaçık bir algoritma:
(\w)(?:(?R)|\w?)\1
At rexegg.com/regex-recursion öğretici nasıl çalıştığını açıklar.
Herhangi bir dilde iyi çalışır, burada kavram kanıtı olarak aynı kaynaktan (bağlantı) uyarlanmış bir örnek, PHP kullanılarak:
$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";
}
çıktılar
dont
o
oo
kook
book
paper
kayak
okonoko
aaaaa
bbbb
Karşılaştırma
Normal ifade ^((\w)(?:(?1)|\w?)\2)$
aynı işi yapar, ancak evet / değil yerine "içerir" olarak.
Not: "o" nun bir palimbrom olmadığı, "mümkün-elba" tireli biçimin bir palindrom olmadığı, ancak "mümkünelba" nın olduğu bir tanım kullanıyor. Tanımın adlandırılması 1 .
"O" ve "olası-elba" palindron olduğunda, adlandırma tanımı2 .
Başka bir "palindrom normal ifadeleri" ile karşılaştırıldığında,
^((.)(?:(?1)|.?)\2)$
yukarıdaki temel normal ifade, \w
kısıtlama olmaksızın , "mümkün-elba" yı kabul eder.
^((.)(?1)?\2|.)$
( @LilDevil ) kullanımı definition2 ( "o" ve bu yüzden "aaaaa" ve "BBB" şeritlerinin tanınmasında da farklı "güçlü-elba" kabul eder).
^((.)(?1)\2|.?)$
( @Markus ) "kook" veya "bbbb" algılanmadı
^((.)(?1)*\2|.?)$
( @Csaba ) Tanım 2'yi kullan .
NOT: karşılaştırmak $subjects
için, karşılaştırılan her normal ifade için için daha fazla kelime ve bir satır ekleyebilirsiniz.
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";