Этот вопрос является образовательной демонстрацией использования lookahead, вложенной ссылки и условных выражений в шаблоне PCRE для соответствия всем палиндромам, включая те, которые не могут быть сопоставлены рекурсивным шаблоном, данным в человеке PCRE стр.суб >
Изучите этот шаблон PCRE в PHP-фрагменте:
$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 нет lookbehind (но он использует conditional).
Кроме того, обратите внимание, что страница PCRE представляет собой рекурсивный шаблон для соответствия некоторым палиндромам:
# the recursive pattern to detect some palindromes from PCRE man page
^(?:((.)(?1)\2|)|((.)(?3)\4|.))$
Страница man предупреждает, что этот рекурсивный шаблон НЕ может обнаружить все палиндромы (см. Почему это рекурсивное регулярное выражение будет соответствовать только тогда, когда символ повторяет 2 n - 1 раз? и также на ideone.com), но вложенный шаблон/позитивный шаблон обзора, представленный в этом вопросе, может.
