Студопедия КАТЕГОРИИ: АвтоАвтоматизацияАрхитектураАстрономияАудитБиологияБухгалтерияВоенное делоГенетикаГеографияГеологияГосударствоДомЖурналистика и СМИИзобретательствоИностранные языкиИнформатикаИскусствоИсторияКомпьютерыКулинарияКультураЛексикологияЛитератураЛогикаМаркетингМатематикаМашиностроениеМедицинаМенеджментМеталлы и СваркаМеханикаМузыкаНаселениеОбразованиеОхрана безопасности жизниОхрана ТрудаПедагогикаПолитикаПравоПриборостроениеПрограммированиеПроизводствоПромышленностьПсихологияРадиоРегилияСвязьСоциологияСпортСтандартизацияСтроительствоТехнологииТорговляТуризмФизикаФизиологияФилософияФинансыХимияХозяйствоЦеннообразованиеЧерчениеЭкологияЭконометрикаЭкономикаЭлектроникаЮриспунденкция |
Использование встроенных переменных
· $^R - результат вычисления утверждения в теле шаблонадля последнего вычисления шаблона, если в нем идет счет или вызывается внешняя программа:
$qwer="lala"; $qwer=~ /x(?{$var=5})/; print $^R; 5 · $n - n-ныйфрагментсовпадения print "$1 $2 $3\n" if(/^(\d)(\w)(\W)$/); · \n - n-ный фрагмент совпадения, вызываемый в самом шаблоне, например поиск гиперссылок:
/a href=(['"])(.*?)\1>/
· $* - разрешает выполнять поиск в многострочных файлах, булева переменная, если она взведена в 1, то символы шаблона поиска ^ и $ сопоставляются позициям перед и после внутренних символов новой строки, если 0, то от начала текста и до конца текста:
$kim="lala\nfa\eti\nzvuki..."; $kim=~~ /^eti/; #совпадение не нашлось $*=1; $kim=~~ /^eti/; #совпадение нашлось
Например, нужно занести в массив только цифры из строчки "12@#34@@#@@###34@@##67##@@#@#@34":
$_='12@#34@@#@@###34@@##67##@@#@#@34'; s/@/#/g; s/(#)\1+/$1/g; print join /\n/, split /#/, $_;
Регулярное выражение s/(#)\1+/$1/g; использует повторение переменной $1 (квантификатор +) и если оно есть, то заменяет все подряд идущие # между цифрами на одну #, содержащуюся в$1(переменная $1 существует, если часть шаблона или шаблон указать в круглых скобках). Допустим нужно определить, все ли цифры числа различны. Попробуем найти хотя бы одно повторяющееся число:
if(/(\d).*(?=\1)/g){ print "по крайней мере одна цифра $1 различна\n"; }
Выражение берет 1-ю цифру и ищет совпадения со всеми остальными, если есть, то говорит, что найдено и заканчивает работу. Регулярное выражение берет первое число при помощи (\d)и начинает его сравнивать со всеми остальными числами при помощи .*(?=\1). Если первое число в строке уникально, регулярное выражение начнет сопоставлять второе число со всеми восемью оставшимися числами. Если и второе число в строке уникально, то берется третье число и сравнивается со всеми остальными. И т.д., если совпадение было найдено, то регулярное выражение возвращает true и заканчивает свою работу, даже если в строке еще есть повторяющиеся числа. Чтобы можно было просмотреть все повторяющиеся числа, можно воспользоваться модификацией предыдущего кода:
$_ = '2314152467'; my @a = m/(\d)(?=\d*\1)/g ; if (@a){ print join(',',@a)," - Repeat\n"; } else{ print "Ok\n" ; } Этот усовершенствованный код работает до тех пор, пока не будут найдены все совпадения, если таковые вообще есть. В perl 5.6 вводятся переменные @- и @+, комбинация которых может заменять переменные $`, $&, и $'. После совпадения шаблона переменная $-[0] содержит начало соответствия текста шаблону, а переменная $+[0] содержит конец соответствия текста шаблону. В начале поиска обе являются нулями. Это значит, что можно вычислить значения $`, $&, и $':
$do = substr($stroka, 0, $-[0]); $sovpalo = substr($stroka, $-[0], $+[0] - $-[0]); $posle = substr($stroka, $+[0]); Например:
$test="11-231234"; $test=~/\d{2}-\d{6}/; print "$-[0], $+[0]"; 0, 9
Соответственно переменные $#- и $#- указывают размерность массивов @- и @+.Переменная $^N.
Как работают регулярные выражения
Регулярные выражения, использующие квантификаторы, могут порождать процесс, который называется перебор с возвратом (backtracking). Чтобы произошло совпадение текста с шаблоном, надо построить соответствие между текстом и всем регулярным выражением, а не его частью. Начало шаблона может содержать квантификатор, который поначалу срабатывает, но впоследствии приводит к тому, что для части шаблона не хватает текста или возникает несоответствие между текстом и шаблоном. В таких случаях perl возвращается назад и начинает построение соответствия между текстом и шаблоном с самого начала, ограничивая "жадность" квантификатора (именно поэтому процесс и называется "перебор с возвратом"). Перечислим квантификаторы perl:
Например, квантификатор + соответствует фразе "один или несколько" и является жадным. Рассмотрим пошагово принцип перебора с возвратом на примере квантификатора +:
'aaabc' =~/a+abc/; a+ сразу в силу жадности совпадает с тремя а:
(aaa)bc, но после aaa не следует строка "abc", а следует "bc". Поэтому результат - failed поэтому анализатор должен откатиться назад и вернуть с помощью a+ два a: (aa)abc,т.е. на втором шаге шаблон найдет совпадение. Рассмотрим пример работы еще одного жадного квантификатора *(ноль или несколько совпадений):
amxdemxg /.*m/ Сначала будет найдена вся строка abcdebfg в силу жадности .*, потом квантификатору нужно будет найти сравнение с буквой m, произойдет ошибка. Квантификатор .* отдаст одну букву и его содержимое будет уже amxdemx. На конце снова нет буквы m. Будет отдана еще одна буква и снова не будет найдено совпадение со всем шаблоном и наконец квантификатор .* будет содержать подстроку amxde, за которой уже стоит символ m. И поиск на этом и закончится не смотря на то, что в строке amxdemxg содержится не одна буква m. Потому и говорят, что квантификаторы обладают жадностью, т.е. находят максимально возможное совпадение. Допустим нужно найти совпадение: $uu="Howareyou? Thanks! I'm fine, you are ok??"; $uu=~s/.*you//; print $uu;
Квантификатор .* оставит текст "are ok??", а вовсе не "? Thanks! I'm fine, you are ok??". Если же поставить ограничитель ?, который вместе со знаком квантификатора означает максимально возможное совпадение
$uu="How are you? Thanks! I'm fine, you are ok??"; $uu=~s/.*you//; print $uu; то переменная $uu будет содержать текст "? Thanks! I'm fine, you are ok??". Предположим нужно найти совпадения типа network workshop, т.е. перекрытия.
$u='network'; $m='workshop'; print "перекрытие $2 найдено: $1$2$3\n" if("$u $m" =~/^(\w+)(\w+) \2(\w+)$/); $1 сразу берет все слово в $u, но дальше идет еще один максимальный квантификатор (\w+), которому тоже чего-то надо и он забирает из переменной \1 букву k(причем только одну):
#!/usr/bin/perl $uu="asdfg asdf"; $uu=/(\w+)(\w+)\s(\w+)(\w+)/; print "$1 $2##$3 $4"; Asdf g##asd f Далее пошаговая работа regex выглядит примерно так:
1: 'networ''k'=> '\sk' совпадает ли с '\sworkshop' falure 2: 'netwo''rk'=> '\srk' совпадает ли с '\sworkshop' falure 3: 'netw''ork'=> '\sork' совпадает ли с '\sworkshop' falure 4: 'net''work'=> '\swork' совпадает ли с '\sworkshop' ok и в результате программа выдаст:
Перекрытие work найдено: networkshop Данный регексп не сработает, если
$u='networkwork'; $m='workshop';
шаблон найдет перекрытия workwork, а не work. Чтобы этого избежать, нужно сделать минимальным \1: /^(\w+?)(\w+) \2(\w+)$/ Квантификатор действует только на предшествующий ему элемент шаблона. Например, конструкция \d{2}[a-z]+ будет соответствовать последовательности из одной или нескольких строчных латинских букв, начинающейся с двух цифр, а не последовательности, составленной из чередующихся цифр и букв. Для выделения группы элементов, на которую действует квантификатор, используются круглые скобки: (\d{2}(a-z])+).
|
||
Последнее изменение этой страницы: 2018-04-12; просмотров: 380. stydopedya.ru не претендует на авторское право материалов, которые вылажены, но предоставляет бесплатный доступ к ним. В случае нарушения авторского права или персональных данных напишите сюда... |