Описание тега roll-through-the-ages
Чтобы найти all1 палиндромов из 3 или более символов, не внутри [...]
:
$ Эхо 'САС[Ады]abacab' | Перл-монтаж '
а (/\[.*?\]|(?=(([^][])(?1)\2|[^][]?))./г) {
печать $1, Если длина 1 $ > = 3
}'
САС
Аба
bacab
ПМа
(заметим, что это предполагает однобайтовых символов, добавить -функция mopen=язык
для язык определение символов).
Основе сопоставления палиндром является рекурсивное регулярное выражение. Палиндром сопоставляется либо как пустая строка или один знак или пара одинаковых персонажей с другой палиндром между ними. Что будет ((.)(?1)\2|.?)
, где (?1)
не рекурсивной части (соответствует тому, что внутри первой части ()
, за исключением того, что здесь мы заменяем .
с [^][]
(любые символы, кроме ]
и [
).
При сопоставлении всех вхождений с /.../г.
, на Perl ищет следующее вхождение после окончания первого, так что если мы \[.*?\]|(([^][])(?1)\2|[^][]?)
, мы бы не найти bacab
в abacab
, потому что он хотел найти Аба
, а затем продолжить поиск после этого Аба
. Так вот вместо этого мы Матч (?=(палиндром)).
который соответствует один символ (.
) при условии, что это в начале палиндром, который затем захватили в $1
. Это означает, что мы возобновляем поиск после этого один символ.
1 Строго говоря, он находит самое длинное (от 3 символов) палиндромы на каждую позицию в строке, пропуская [...]
ы, поэтому он не может найти все вхождения. Например, в Абебы
, она нашла бы Абебы
в первой позиции, баб
в третью позицию, Аба
на второй позиции, но не абы
в первой позиции.