Студопедия

КАТЕГОРИИ:

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

Here is the number of apples: 4.




 

Каждой паре скобок внутри шаблона после завершения операции поиска будет соответствовать скалярная переменная с соответствующим номером. Это можно использовать при выделении нужных для последующей работы фрагментов анализируемой строки. В следующем примере мы изменяем порядок трех слов в текстовой строке с помощью командыs/.../.../:

 

$text = "I see you.";

$text=-s/^(\w+) *(\w+) *(\w+)/$3 $2 $1/;

print $text;

You see I.

 

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

 

$text = "ABCDEFGH";

$text =- m/(\w(\w)(\w))((\w)(\w))/;

print "$1/$2/$3/$4/$5/$6/";

ABC/B/C/DE/D/E

 

Кроме переменных, ссылающихся на найденный текст, можно использовать специальные переменные perl.

 

Функции, использующие регулярные выражения

 

Фактически, есть три функции, которые в качестве разделителя могут использовать регулярные выражение: split, grep, map и еще можно воспользоваться специальными операторами ...и .. и используемыми совместно с ними условиями if, unless и просто логическими операторами.

 

Split

 

Если необходимо разделить данные из STDIN по нужному разделителю, то можно воспользоваться локализацией $/:

 

subexample_local{

local $/ = undef;

@mass= split /pattern/, <>;

return 1;

}

printscalar(@mass);

 

Можно разделять данные из файла и так:

 

undef $/;

@res=split /pattern/, <F>;

чтоэквивалентно:

while (<F>) {push @asdf, split}

 

После split можно ставить вместо запятой и стрелочку:

 

@mass = split /(\d){4}/ => $file;

 

В функции сплит можно воспользоваться максимальным квантификатором *, который в том числе и 0 символов, позволит разделить строку на символы, которых там нет(в силу того, что * это 0 и более символов), т.е. посимвольно:

 

@ruru = split /\001*/ => "lalalalalala";

 

#массив @ruru будет содержать элементы по одной букве.

Если строка состоит из нескольких строк, то можно поставить разделителем и символ начала новой строки:

 

$str = "asdf\nghjk\nqwer\n";

@lines = split /^/ => $str;

 

Вобщем, в split можно вставлять любой поиск по шаблону.

 

Grep

 

Функция grep также позволяет заполнять массив значениями. Например, нужно получить список расширений файлов в заданной директории:

 

while(<$dir/*.*>){push @files, $_}        #читаем директорию

@test = grep { s|.*/(.*?)\.(.*)|$2| } @files; #оставляем в директории только расширения файлов

 

можно использовать признак четности для занесения в массив:

 

@test1=qw(1 2 3 4 5 6 7 8 9);

@evens = grep($_%2 == 1) @test1;

 

Или более сложное регулярное выражение для вытаскивания всех e-mail адресов из текстовой странички:

 

@mass=grep{s/(.*) ([\w+\-\.]+\@[\w\-\.]+\.\w{2,3})(.*)/$2/ig} split /\n/, $test;

Здесь используется укороченная запись:

 

@mass=grep {/pattern/} split /\n/, $test;

которая эквивалента записи из двух строчек:

@uuu=split /\n/, $test;

@mass=grep {/pattern/} @uuu;

 

Map

 

Функция map похожа по своей работе на обычное условие if, допустим нужно разделить записи на блоки, разделенные четырьмя пробелами:

 

@probel = map m!\s{4}!, split /\n/, $test;

 

Other

 

Вывод строк из заданного интервала для данной строки:

 

if(/pattern1/i .. /pattern2/i){...}

#истинность первого оператора включает конструкцию, а второго е выключает.

if($nomer1 .. $nomer2){...}

 

... не возвратит истину, в отличии от .., если условия выполняются в одной строке.

 

if(/pattern1/i ... /pattern2/i){...}

if($nomer1 ... $nomer2){...}

 

для многострочного файла

 

Print -ne 'printif 3 .. 15' file.txt

 

выведет строки файла с 3 по 15 строчку, таже самая операция но немного по другому:

 

open F, "<file";

while(<F>){

Print if(3 .. 15)

}

 

или с какой-нибудь начальной и конечной разметкой. Например, есть вспомогательный файл шаблонов(просто различные виды html, в зависимости от действия пользователя) для разных определенны случаев, которые нужны исходя из контекста программы:

 

open F, "<file";

while(<F>){

print if(/<!--begin welcome-->/i ... /<!--end welcome-->/i)

}

 

Такая конструкция позволяет выводить куски многострочного html кода(для однострочного нужно ставить оператор ..). Условия в таких операторах можно ставить и разнотипными

 

$file=qr/2345/;

while(<F>){

print if(/^$/ .. 10); #увидим, что находится от пустой до 10-й строки

print if(/^\001/ .. /$file/); #выведет все, что после нуля и до того что задано qr

}

 

Программа чтения почтовых адресов из mbox или sent-mail:

 

while(<F>){

next unless /^From:?\s/i .. /^$/;

while (/([^<>(,;)\s]+\@[^<>(,;)\s]+)/)g{

print "$1\n" unless $test{$1}++;

}

}

запускается ./regex.pl /root/mail/sent-mail и выводит каждый емейл по одному разу.

 










Последнее изменение этой страницы: 2018-04-12; просмотров: 405.

stydopedya.ru не претендует на авторское право материалов, которые вылажены, но предоставляет бесплатный доступ к ним. В случае нарушения авторского права или персональных данных напишите сюда...