Использование специальных ссылок в сохраняющих круглых скобках для проверки



Когда часть 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; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!