Студопедия

КАТЕГОРИИ:

АвтоАвтоматизацияАрхитектураАстрономияАудитБиологияБухгалтерияВоенное делоГенетикаГеографияГеологияГосударствоДомЖурналистика и СМИИзобретательствоИностранные языкиИнформатикаИскусствоИсторияКомпьютерыКулинарияКультураЛексикологияЛитератураЛогикаМаркетингМатематикаМашиностроениеМедицинаМенеджментМеталлы и СваркаМеханикаМузыкаНаселениеОбразованиеОхрана безопасности жизниОхрана ТрудаПедагогикаПолитикаПравоПриборостроениеПрограммированиеПроизводствоПромышленностьПсихологияРадиоРегилияСвязьСоциологияСпортСтандартизацияСтроительствоТехнологииТорговляТуризмФизикаФизиологияФилософияФинансыХимияХозяйствоЦеннообразованиеЧерчениеЭкологияЭконометрикаЭкономикаЭлектроникаЮриспунденкция

Использование встроенных переменных




  • $' - подстрока, следующая за совпадениемс шаблоном поиска, можно только читать;
  • $& - совпадение с шаблоном поискапри последней операции поиска или замены. В отличии от переменной $_, эту переменную переопределять как вздумается нельзя;
  • $` - подстрока, расположенная перед совпадениеразрешается только чтение;

· $^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:

  • * - ноль или несколько совпадений;
  • + - одно или несколько совпадений;
  • ? - ноль совпадений или одно совпадение;
  • {n}- ровно n совпадений;
  • {n,}- по крайней мере n совпадений;
  • {n,m}- от n до m совпадений.

Например, квантификатор + соответствует фразе "один или несколько" и является жадным. Рассмотрим пошагово принцип перебора с возвратом на примере квантификатора +:

 

'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 не претендует на авторское право материалов, которые вылажены, но предоставляет бесплатный доступ к ним. В случае нарушения авторского права или персональных данных напишите сюда...