Использование специальных ссылок в сохраняющих круглых скобках для проверки
Когда часть if представляет собой число в круглых скобках, условие считается истинным, если пара сохраняющих круглых скобок с заданным номером уже участвовала в совпадении к настоящему моменту. В следующем примере ищется совпадение для тега HTML <IMG>, отдельного или заключенного между тегами <А>…</А>. Выражение приведено в режиме свободного форматирования с комментариями, а условная конструкция (которая в данном случае не содержит части else) выделена полужирным шрифтом:
( <A\s+[^>]+> \s* )? # Совпадение для открывающего
тега <А>, если он есть.
<IMG\s+[^>]+> # Совпадение для тега <IMG>.
(?(1)\s*</A>) # Совпадение для закрывающего тега <А>,
если ранее # было найдено совпадение для <А>.
Условие (1) в (?(1)…) проверяет, участвовала ли первая пара сохраняющих круглых скобок в совпадении. «Участие в совпадении» принципиально отличается от «фактического совпадения с текстом», как наглядно показывает следующий пример.
Рассмотрим два выражения для представления слова, заключенного в необязательные угловые скобки «<…>». Решение (<)?\w+(?(1)>) работает, а решение (<?)\w+(?(1)>)- нет. Между ними существует единственное различие - позиция первого вопросительного знака. В первом (правильном) выражении вопросительный знак относится к сохраняющим скобкам, поэтому сами скобки (и все, что находится внутри них) не обязательны. Во втором (ошибочном) решении сохраняющие скобки обязательны - не обязательно лишь совпадение < внутри них, поэтому они «участвуют в совпадении» независимо от того, совпал символ < или нет. Это означает, что условие if в выражении (?(1)-) всегда истинно.
|
|
При поддержке именованных сохранений вместо номера в скобках обычно может указываться ассоциированное имя.
Использование позиционной проверки
В условиях if также могут использоваться полные конструкции позиционной проверки, такие как (?=…) и (?<=…) Если для проверяемого выражения находится совпадение, условие считается истинным и тогда применяется часть then. В противном случае применяется часть else. Сказанное можно пояснить несколько запутанным примером: (?(?<=NUM: )\d+|\w+). Приведенное выражение пытается найти совпадение для \d+ в позициях после NUM: , а в других позициях ищется совпадение для \w+. Условие позиционной проверки подчеркнуто.
Другие способы проверки условий
В Perl условная конструкция обладает интересной особенностью: в качестве условия может быть задан произвольный фрагмент кода Perl. Возвращаемое значение этого фрагмента определяет, какая часть условной конструкции должна применяться (then или else).
|
|
7. Максимальные квантификаторы: *, +, ?, {мин, макс}
Квантификаторы (*, +, ? и интервальная конструкция - метасимволы, определяющие количество экземпляров повторяющегося элемента) рассматривались в одной из предшествующих глав. Следует помнить, что в некоторых программах вместо + и ? используются \+ и \?. Кроме того, в отдельных программах квантификаторы не могут применяться к обратным ссылкам или выражениям, заключенным в скобки.
Интервалы: {min, max} или \{min, max\}
Интервальный квантификатор «ведет счет» найденных экземпляров совпадения. Он определяет наименьшее количество обязательных и наибольшее количество допустимых экземпляров. Если указывается только одно число ([a-z]{3} или [a-z]\{3\} в зависимости от диалекта) и этот синтаксис поддерживается программой, совпадает в точности заданное количество экземпляров. Этот пример эквивалентен [a-z] [a-z][a-z], хотя в разных программах эффективность их применения различается.
Предупреждение: не стоит полагать, что конструкция вида Х{0, 0} означает «здесь не должно быть X». Выражение Х{0, 0} бессмысленно, поскольку оно означает: «ни один экземпляр X необязателен, так что можно даже не пытаться их искать». Это равносильно тому, что конструкция Х{0,0}jвообще отсутствует - если даже элемент X и есть, он может совпасть с одной из следующих частей выражения, поэтому исходный смысл этой конструкции полностью утрачивается. Для проверки условия типа «здесь не должно быть» следует использовать негативную опережающую проверку.
|
|
8. Минимальные квантификаторы: *?, +?, ??, {мин, макс}?
В некоторых программах поддерживаются нескладные конструкции *?, +?, ?? и {min, max}?. Они представляют собой минимальные версии квантификаторов. Обычные квантификаторы руководствуются критерием максимального совпадения и пытаются найти совпадение как можно большей длины. Минимальные версии ведут себя совершенно противоположным образом и ищут совпадение наименьшей длины, удовлетворяющее заданному критерию. Различия между двумя разновидностями квантификаторов имеют ряд принципиальных аспектов, подробно рассматриваемых в следующей главе.
9. Захватывающие квантификаторы: *+, ++, ?+, {мин, макс}+
Захватывающие (possessive) квантификаторы в настоящее время поддерживаются только пакетом Java.util.regex и PCRE (т.е. PHP), но можно предположить, что они получат более широкое распространение в будущем. Захватывающие квантификаторы ведут себя как обычные максимальные квантификаторы, но после того, как им будет назначено совпадение, они ни при каких условиях не «возвращают» захваченные символы. Как и в случае с атомарной группировкой, захватывающие квантификаторы гораздо проще понять при хорошем знании общих принципов поиска совпадения (эта тема рассматривается в следующей главе).
|
|
В определенном смысле захватывающие квантификаторы относятся к «синтаксическим удобствам», поскольку их можно имитировать при помощи атомарной группировки. Конструкция вида .++ в точности эквивалентна (?>.+), хотя грамотные реализации оптимизируют захватывающие квантификаторы лучше, чем атомарную группировку.
Дата добавления: 2018-04-04; просмотров: 314; Мы поможем в написании вашей работы! |
Мы поможем в написании ваших работ!