Анимация
JavaScript


Главная  Библионтека 

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 [ 100 ] 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189

более совпадений" - символом плюса +. С его помощью можно было бы выражение записать лаконичнее: a-+, что буквально и читается как "a и один или более минусов". Вот пример выражения, которое определяет, есть ли в строке английское слово, написанное через дефис: [a-zA-z]+-[a-zA-z]+.

Ноль или одно совпадение

И уж чтобы совсем облегчить жизнь, иногда используют еще один квантификатор - знак вопроса ?. Он обозначает, что предхдущий символ может быть повторен ноль или один (но не более!) раз. Например, выражение [a-zA z]+\r?\n определяет строки, в которых последнее слово прижато к правому краю строки. Если мы работаем в Unix, то там в конце строки символ \r обычно отсутствует, тогда как в текстовых файлах Windows каждая строка заканчивается парой \r\n. Для того чтобы сценарий правильно работал в обоих системах, мы должны учесть эту особенность - возможное наличие \r перед концом строки.

Заданное число совпадений

Наконец, давайте рассмотрим последний квантификатор повторения. С его помощью можно реализовать все перечисленные выше возможности, правда, и выглядит он несколько более громоздко. Итак, сейчас речь пойдет о квантификаторе "фигурные скобки". Существует несколько форматов его записи. Давайте последовательно разберем каждый из них.

□ X{n,m} - указывает, что символ X может быть повторен от n до m раз;

□ X{n} - указывает, что символ X должен быть повторен ровно n раз;

□ X{n,} - указывает, что символ X может быть повторен n или более раз.

Значения n и m в этих примерах обязательно должны принадлежать диапазону от 0 до 255 включительно. В качестве тренировки вы можете подумать, как будут выглядеть квантификаторы *, + и ? в терминах {...}.

Мнимые символы

Мнимые символы - это просто участок строки между соседними символами (да, именно так, как это ни абсурдно), удовлетворяющий некоторым свойствам. Фактически, мнимый символ - это некая позиция в строке. Например, символ соответствует началу строки (заметьте: не первому символу строки, а в точности началу строки, позиции перед первым символом), а $ - ее концу (опять же, позиции за концом строки).

Чтобы это понять, давайте рассмотрим вхражение abc, которое соответствует любой строке, начинающейся с abc, и вхражение abc$, соответствующее строке с abc на "хвосте". Наконец, вхражение abc$ сопоставимо только со строкой abc, и в этом смысле оно эквивалентно сравнению на равенство.



Существуют еще два мнимых символа, задающих начало и конец слова. Первый из них обозначается как [[:<:]] и указывает на позицию перед первой буквой очередного слова. Последний записывается в виде [[:>:]] и сигнализирует о позиции после последнего символа слова. Под словом здесь понимается фрагмент строки, удовлетворяющий вхражению [[:alnum:]]+, т. е., любая последовательность из букв и

цифр.

Примечание

Язык RegEx поддерживает только четыре уже рассмотренных нами мнимых символа. Этого нельзя сказать о формате PCRE, в котором, наоборот, количество таких символов доведено до абсурда.

Вот пример использования мнимых символов: $st=" string ";

if(ereg("[[:<:]]([[:alnum:]]+)[[:>:]]",$st,$Pock)) echo "Найдено слово: $Pock[1]";

Оператор альтернативы

При описании простых символов мы рассматривали конструкцию [... ] , которая позволяла нам указывать, что в нужном месте строки должен стоять один из указанных символов. Фактически, это не что иное, как оператор альтернативы, работающий только с отдельными символами (и потому довольно быстро).

Но в языке RegEx есть возможность задавать альтернативы не одиночных символов, а сразу их групп. Это делается при помощи оператора .

Вот несколько примеров его работы.

□ Вхражение 123 полностью эквивалентно вхражению [123], но сопоставление происходит несколько медленнее.

□ Вхражению aaaaz$zzz соответствуют строки, в которых есть подстрока aaa , либо которые начинаются на a , либо оканчиваются на z , либо, наконец, содержат подстроку zzz .

□ Выражению abc1abc22abc333 соответствуют строки, в которых встречаются подстроки abc1, abc22 или abc333 (а возможно, и все три одновременно).

Группирующие скобки

Последний пример наводит на рассуждения о том, нельзя ли как-нибудь сгруппировать отдельные символы, чтобы не писать по несколько раз одно и то же. В нашем примере строка abc встречается в вхражении аж 3 раза. Но мы не можем написать выражение так: abc122333, потому что оператор , естественно, пытается применить себя к как можно более длинной последовательности команд.



Именно для цели управления оператором альтернативы (но не только) и служат группирующие круглые скобки (... ) . Нетрудно догадаться по смыслу, что выражение из последнего примера можно записать с их помощью так: abc(122333).

Конечно, скобки могут иметь произвольный уровень вложенности. Это бывает полезно для сложных выражений, содержащих много условий, а также для еще одного применения круглых скобок, которое мы сейчас и рассмотрим.

"Карманы"

Пока что мы научились только определять, соответствует ли строка регулярному выражению и, возможно, предпринимать какие-то действия по замене найденной части на другую подстроку. Однако на практике часто бывает нужно не просто узнать, где в строке имеется совпадение (и что оно из себя представляет), но также и разбить это совпадение на части, ради которых, собственно, и велась вся работа.

Вот пример, проясняющий ситуацию. Пусть нам в строке задана дата в формате DD-MM-YYYY, и в ней могут встретиться паразитные пробелы в начале и конце. Нас интересует, что же все-таки за дату нам передали. То есть, мы точно знаем, что эта строка - именно дата, но вот где в ней день, где месяц и где год?

Посмотрим, что же предлагает нам RegEx и PHP для решения рассматриваемой задачи. Для начала установим, что все правильные даты должны соответствовать выражению

- *(([0-9]+)-([0-9]+)-([0-9]+)) *$

Для простоты мы не проверяем, что длина каждого поля не должна превышать 2 (для года - 4) символа. Все строки, не удовлетворяющие этому вхражению, заведомо не являются датами.

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

Примечание

Обратите еще раз внимание на порядок нумерации карманов - она идет по номеру открывающейся скобки.

Как уже упоминалось, в нулевой карман в любом случае записывается все найденное совпадение. В данном примере это будет вся строка.

Как получить содержимое наших карманов? Очень просто: как раз тот список, который передается по ссылке функции ereg() третьим параметром, и есть карманы.



0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 [ 100 ] 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189