После чтения polygenelubricants серии статей по передовым методам регулярных выражений (особенно Как это регулярное выражение Java обнаруживает палиндромы?), я решил попытаться создать собственное регулярное выражение PCRE для анализа палиндрома, используя рекурсию (в PHP).
То, что я придумал, было:
^(([a-z])(?1)\2|[a-z]?)$
Мое понимание этого выражения состоит в том, что оно должно либо соответствовать нулю, либо одному символу (каждая строка из менее чем двух символов неявно является палиндром, а также для учета палиндромов с нечетной длиной в рекурсии) или два из один и тот же символ, разделенный рекурсией шаблона.
К сожалению, похоже, что это не так, как вы можете видеть на www.ideone.com/a9T3F. Вместо этого только строки 2 n - 1 (т.е. Пустая строка, a
, aaa
, aaaaaaa
, a 15) повторяющиеся символы соответствуют регулярному выражение.
Как ни странно, если я изменяю свой шаблон так, чтобы рекурсия была необязательной (т.е. ^(([a-z])(?1)?\2|[a-z]?)$
, см. www.ideone.com/D6lJR, это только соответствует строкам с повторением символа 2 n (т.е. пустая строка, a
, aa
, aaaa
, aaaaaaaa
, a 16).
Почему мое регулярное выражение не работает так, как я ожидаю?
Примечание для людей, которые испытывают зуд, предлагая не использовать регулярное выражение:
В этом вопросе нужно научиться правильно использовать рекурсивные регулярные выражения. Я знаю, что это не эффективный способ определить, является ли строка палиндром, и я бы не использовал рекурсивное регулярное выражение, если мне почему-то пришлось определять палиндромы в производственном коде; Мне просто интересно узнать больше о расширенных аспектах регулярного выражения.