この質問は、PCREのマニュアルページに記載されている再帰パターンでは一致しないパリンドロームを含む、すべてのパリンドロームに一致するPCREパターンでの先読み、ネストされた参照、および条件の使用法の教育的なデモンストレーションです。
PHPスニペットでこのPCREパターンを調べます。
$palindrome = '/(?x)
^
(?:
(.) (?=
.*
(
\1
(?(2) \2 | )
)
$
)
)*
.?
\2?
$
/';
このテストケースで見られるように、このパターンはパリンドロームを検出しているようです(ideone.comも参照)。
$tests = array(
# palindromes
'',
'a',
'aa',
'aaa',
'aba',
'aaaa',
'abba',
'aaaaa',
'abcba',
'ababa',
# non-palindromes
'aab',
'abab',
'xyz',
);
foreach ($tests as $test) {
echo sprintf("%s '%s'\n", preg_match($palindrome, $test), $test);
}
では、このパターンはどのように機能しますか?
ノート
このパターンはネストされた参照を使用します。これは、このJava正規表現がパリンドロームをどのように検出するかで使用されるのと同様の手法です。、ただし、そのJavaパターンとは異なり、後読みはありません(ただし、条件付きを使用します)。
また、PCREのマニュアルページには、いくつかのパリンドロームに一致する再帰的なパターンが示されていることに注意してください。
# the recursive pattern to detect some palindromes from PCRE man page
^(?:((.)(?1)\2|)|((.)(?3)\4|.))$
マニュアルページは、この再帰パターンがすべてのパリンドロームを検出できるわけではないことを警告しています(文字が2 n -1回繰り返された場合にのみこの再帰正規表現が一致するのはなぜですか?またideone.comを参照)が、ネストされた参照/ポジティブ先読みパターンが表示されますこの質問ではできます。