Опубликован: 18.06.2007 | Доступ: свободный | Студентов: 1420 / 43 | Оценка: 4.14 / 3.29 | Длительность: 12:44:00
ISBN: 978-5-94774-604-4
Лекция 2:

Механизм работы регулярных выражений. Поиск с возвратами

< Лекция 1 || Лекция 2: 1234 || Лекция 3 >

Рассмотрим еще один пример. Пусть мы имеем шаблон

abcd|abc|ab

и строку

ab

Когда механизм поиска обрабатывает конструкцию выбора, он пытается найти совпадение с одной и той же текущей позиции текста, пробуя для нее последовательно эти подшаблоны в порядке их записи (слева направо). Если какой-то подшаблон совпал, то механизм поиска пропускает оставшиеся подшаблоны из конструкции выбора и далее переходит к подшаблону, стоящему за этой конструкцией.

В нашем примере сначала будет попробован подшаблон abcd, эта проба закончится неудачей. Также неудачей закончится проба следующего подшаблона abc. И только последний подшаблон ab совпадет. Если бы после этой конструкции выбора шаблон продолжался и следующий за ней подшаблон не совпал, то в общем случае произошел бы возврат к этой конструкции выбора и в дело пошел бы следующий за ab подшаблон (если бы он существовал). В этом примере ab - последний подшаблон, поэтому в общем случае возврат продолжился бы еще левее, за конструкцию выбора и так далее до самого начала всего шаблона. И только в случае, когда при всевозможных значениях квантификаторов и номеров подшаблонов в конструкциях выбора совпадение не было бы найдено, произошло бы продвижение начальной позиции поиска в тексте на один символ.

На этом примере надо усвоить одно важное правило использования конструкций выбора: если в такой конструкции есть подшаблоны, которые могут совпасть с текущей позицией текста, то имеет значение порядок следования этих подшаблонов. Представим, что имеется шаблон

(ab|abc)\w*

и строка

abc

Первый, более короткий подшаблон совпадет, и текущая позиция в шаблоне перейдет за конструкцию выбора. А нам, может быть, хотелось бы, чтобы совпал более длинный подшаблон abc. В этом случае его надо ставить раньше подшаблона ab. Вот еще более очевидный пример: в конструкции выбора

.*|abc

первый подшаблон может совпасть с текущей позиции текста всегда при нулевом значении квантификатора *. До попытки применить вторую альтернативу очередь никогда не дойдет, как будто ее нет вовсе!

Когда происходит возврат в шаблоне за подшаблон с квантификаторами, то запомненные состояния для всех квантификаторов в этом подшаблоне сбрасываются, чтобы при следующем движении по шаблону вправо они работали с начала. Аналогично, номера подшаблонов в конструкциях выбора сбрасываются в нуль.

Такой алгоритм поиска называется недетерминированным конечным автоматом (НКА). Этот алгоритм управляется шаблоном, и программист может указать, какое именно совпадение ему нужно. Существуют другие алгоритмы поиска (детерминированный конечный автомат ДКА или смешанные алгоритмы), но в языке Perl и других языках и библиотеках (PHP, PCRE) применяется НКА, хотя он не самый быстрый среди алгоритмов поиска. Программисту, привыкшему к алгоритму НКА, другой язык программирования, который использует другой алгоритм поиска, может преподнести сюрприз. Я уже не говорю о том, что в других языках некоторые метасимволы могут работать иначе, чем в Perl.

Рассмотрим еще примеры:

$_='abcd';
/(\w+)(\w+)/;
print "$1|$2";

Сначала первая пара скобок захватит всю строку, но во имя нахождения совпадения для всего шаблона пожертвует одним символом для второй скобки. В результате будет напечатано abc|d. Если во второй паре скобок вместо плюса стояла бы звездочка или вопросительный знак, то на их долю вообще не осталось бы символов - все их поглотил бы квантификатор из первой пары скобок, и переменная $2 получила бы пустое значение. Вот она, "жадность" в действии. Каждый "жадный" квантификатор оставляет остальной части шаблона минимум символов, лишь бы нашлось совпадение.

Минимальные квантификаторы действуют наоборот: берут себе минимум символов, а оставляют максимум для нахождения совпадения. Конструкция же выбора не минимальна и не максимальна, она упорядочена по очереди появления в ней альтернативных подшаблонов.

Возьмем шаблон

12?3

и строку

123

Т.к. квантификатор ? жаден, то вначале будет попробован вариант с его максимальным значением, которое равно единице. Но перед этим будет создано сохраненное состояние:

в шаблоне 1.3
в строке 1.23

где точкой обозначена текущая позиция поиска. Подшаблон 2? совпадет с 2, а 3 совпадет с символом 3. Совпадение будет найдено с первой попытки, и сохраненное состояние не вступит в игру, а если бы и вступило, то не привело бы к успеху поиска.

Теперь рассмотрим работу этого шаблона на строке

13

Вначале литерал 1 совпадет с символом 1 в строке. Далее 2? с максимальным значением квантификатора, а это просто 2, не совпадет с символом 3. Но перед этим создается сохраненное состояние:

в шаблоне 1.3
в строке 1.3

При этой локальной неудаче произойдет возврат к последнему сохраненному состоянию, который приведет к совпадению литерала 3 с символом 3, и поиск закончится удачно.

< Лекция 1 || Лекция 2: 1234 || Лекция 3 >
Гулзира Урбисинова
Гулзира Урбисинова
Сергей Крупко
Сергей Крупко

Добрый день.

Я сейчас прохожу курс  повышения квалификации  - "Профессиональное веб-программирование". Мне нужно получить диплом по этому курсу. Я так полагаю нужно его оплатить чтобы получить диплом о повышении квалификации. Как мне оплатить этот курс?