от Курс за ССОК
Увод в програмирането на Perl
Лекция #7 Регулярни изрази
Лектори /гости от курса по Perl в Софийски Университет/
- Николай Бачийски nbachiyski@developer.bg
- Васил Сакъров vasil_sakarov@developer.bg
Що е и за какво е то?
- има ги в почти всички модерни езици за програмиране
- представяне като низ на крайни автомати
- търсят се съвпадения на даден шаблон в низ
- лесно може да се заменя текст, отговарящ на шаблон
- обработка на текстови данни в определен формат (например: comma separated values)
- универсален начин за валидация на данни
Прости примери
- По подразбиране работят върху $_, ако са оградени от /:
/regexp/
- Всички неспециални символи (буквите например) отговарят на себе си
- /baba/ търси подниз на $_ "baba"
- $str =~ /baba/ - същото но в $str
- В скаларен контекст операторът =~ връща истина, ако е намерил подниз, който отговаря на шаблона
pass_through() if ($input =~ /baba/);
- Ако използваме за разделители // можем да пропуснем оператора m
$str =~ m|N/A|
- За замяна на подниз с друг използваме оператора s:
$str =~ s/baba/dyado/
- В този случай се променя стойността на променливата $str
Особености
- При търсенето се прави разлика между малки и главни букви, освен ако не е указан модификатора i:
"bubabadi" =~ /BABA/ # ще намери нищо
"bubabadi" =~ /BABA/i # о, да!
- В регуларните изрази се интерполират променливи
$dyado = "ba";
$str =~ /ba$dyado/; # ще търси baba
- Има купчина специални за регуларните изрази символи. Ако искаме да ги използваме като тях самите трябва да поставим \ отпред. Ето ги и тях:
{ } [ ] ( ) ^ $ . | * + ? \
По-сложни примери
- | се използва за избор между няколко възможни низа
/баба|дядо/
/баба иска боза|дядо иска боза/
/(баба|дядо) иска боза/
Повторения
- нещо? - Намира "нещо" 0 или 1 път
- нещо* - Намира "нещо" 0 или повече пъти
- нещо+ - Намира "нещо" 1 или повече пъти
- нещо{n} - Намира "нещо" точно n пъти
- нещо{n,} - Намира "нещо" поне n пъти
- нещо{n,m} - Намира "нещо" поне n пъти, но по малко от m
Пример:
/тралала(лала)?/
# съгласува се с "тралала" или "тралалала"
/тралала(лала)*/
# съгласува се с "тралала", "тралалалала", "тралалалалала" и т.н.
/тра(лала)+/
# аналогично на предния пример
/тра(ла){2}/
# съгласува се с "тралала"
/тра(лала){1,}/
# аналогично на втория пример
/тра(лала){1,2}/
# съгласува се с "тралала" и "тралалалала"
/тралала+/
# съгласува се с тралала, тралалаа, тралааа…
Символни класове
- лесно описване на група символи без използване на |
[abcdef]
[a-f\w]
[^A-Z]
- Вградени символни класове:
- . - съвпада с произволен символ
- \d ([0-9]) - цифра
- \D ([^0-9]) - нецифра
- \s - празно място
- \S - непразно място
- \w - букви, цифри, подчертавка - дума
- \W - всичко различно от \w (не дума)
Резултати от прилагане на регулярни изрази
- искаме да вземем деня, месеца и годината от \d\d-\d\d-\d{4}
- скобите не са това, което са!
if($date =~ /(\d\d)-(\d\d)-(\d{4})/) { print "day: $1, month: $2, year: $3"; }
- В $1..$9 се съдържат поредните оградени от скоби съвпадения
- В $& се намира намерения низ
- В $` се намира частта преди намерения низ
- В $' се намира частта след намерения низ
- Стойностите на тези специални променливи остават или до края на блока или до следващото съгласуване с регулярен израз
Още специални символи и особености
- ^, $ - начало и край на низ
if($name =~ /\w+/) { print "OK!\n"; }
или
if ($name =~ /^\w+$/) ...
- Алчно копеле е машината за регуларни изрази
$str = "baaabaaaab"
$s =~ /a+/ # aaa
$s =~ /a+?/ # a
$s =~ /a*/ # :)
$s =~ /ba*/ # baaa
Задачи
Задача 1
Да се напише програма, която премахва символите !@#$^%&*()_+ от даден низ.
Задача 2
Да се напише програма, която връща сумата от всички числа, които се срещат в даден низ.
Задача 3
Да се напише програма, която проверява за валиден формат на email.
Решения