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

$string = «one two three four five»;
$string =~ m/three/;

print $`; # результат: «one two «
print $’; # результат: » four five»
print $&; # результат: «three»
# теперь насчет массивов @+ и @-
print $-[0]; # результат: 8
print $+[0]; # результат: 13
# переменные $#-, $#+ указывают на длину @-, @+ соответственно
# с помощью функции substr() можно получить переменные $`, $’, $&, например

$before_pat = substr($string,0,$-[0]); # аналог $`
$after_pat = substr($string,$+[0]); # аналог $’
$pattern = substr($string,$-[0],$+[0]-$-[0]); # аналог $&

Переменная $^R, пример:

$string = «some text»; 
$qwer =~ /(?{$var1=2.3;$var2=3.2})/; 
print $^R;

Результат: 3.2
Переменная $+, пример:

$string = «some text»; 
$string =~ m/(\w+)\s+(\w+)/; 
print $+;

Результат: text
Переменная $*, пример:

$string = «couple\nof\nlines\ngoes\nbellow…»;
print $string =~ m/^lines/; # в этом случае пустая строка «»
$*=1; # после присвоения переменной $* истины, результат будет
print $string =~ m/^lines/; # — истина

Используем модификатор e для оператора s/…/…/:

$string = «words don’t come easy»;
$string =~ s/(\w+)/uc($1)/eg;
print $string;

Данный фрагмент кода «поднимает» регистр букв у всех слов из строки $string (глобально),
вот что получается:

WORDS DON’T COME EASY

Что такое альтернатива? Это вот что:
Данный фрагмент:


while(<>){
if(/^exit$/){last}
if(/^quit$/){last}
if(/^stop$/){last}
}


Можно заменить этим, с использованием альтернативы:


while(<>){
#
это перебор с сравнением с текстом, т.е. если хотя бы один фрагмент из
#
альтернативы совпадет с текстом, то возвращаемое значение примет истину.
#
т.е. в данном случае если
пользователь введет в STDIN, exit или quit или же
stop,

#
то мы завершим цикл
if(/^(quit|exit|stop)$/){
last;
}
}

Нужно проверить есть ли в строке слово ALPHA и слово BETA:


$string = «BETALPHA»;
if(($string =~ /ALPHA/) and ($string =~ /BETA/)){
print «OK»;
}

Или так:


if($string =~ /(?=.*ALPHA)(?=.*BETA)/){ #
так не делать — пример для перекрывающихся совпадений
print «OK»;
}



$string =~ /^(?:(?!PAT).)*$/

Выражение истинно если шаблон /PAT/ не совпадает (аналогично $string !~
/PAT/): 
Далее насчет конструкций (?=шаблон) и т.д.:

В следующем примере ищется слово, за которым следует три восклицательных знака, но сам
пробел не включается в результат поиска:


$string = «One! Two!! Three!!! And some words next…»;
$string =~ m/(\w+(?=!!!))/;
print $1;

Ответ: Three.

Вот тоже неплохой пример, взятый из книги Perl
Cookbook.


$string = «1234567890»;
@nonlap = $string =~ /(\d\d\d)/g;
@yeslap = $string =~ /(?=(\d\d\d))/g;
print «Non-overlapping: @nonlap\n»;
print «Overlapping: @yeslap\n»;

Вот, что получается:

Non-overlapping: 123 456 789
Overlapping: 123 234 345 456 567 678 789 890

Идем дальше — совпадение с любым символом, т.е. точка (.), например:


$string = «secret password»;
$string =~ s/./*/g;
print $string;

Хоть * — это квантификатор, но в данном случае предшествующего элемента нет поэтому
используется лексическое значение, и результат, такой:

**************

Но мнимый символ точка не совпадает с символом переноса строки, вот пример:

$string = «some text\nnew string»;
$string =~ s/./*/g;
print $string;

Вот вывод программы:

*********
**********

Перенос строки остался, чтобы разрешить точке совпадать с переносом строки,
нужно добавить модификатор s, и все:

$string = «some text\nnew string»;
$string =~ s/./*/gs;
print $string;

Результат:

********************

То, что нужно… Проверяем, в строке $string больше 80 символов или нет:

$string = «simple text»;
$_ = $string;
if(/.{80,}/){
print «Length of text is OK»;
}else{
print «Length of text isn’t OK»;
}

Теперь поговорим о квантификаторах.

$string = «It is some text!!!!!!!!!!!!!!!!!»;
$string =~ s/!+/!/;
print $string;

В этом случае вывод будет таков:

It is some text!

Квантификатор + означает одно или более совпадений, но т.к. квантификаторы количества изначально
являются «жадными» (о жадности квантификаторов ниже), то в данном случае квантификатор + заменит
самую длинную последовательность восклицательных знаков, а вот если поставить этот
квантификатор — *, то в первом случае он отработает также, но если строку заменить на эту:

$string = «It is some text»;

Тогда результат будет следующим:

!It is some text

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

$string = «It is some text!!!!!!!!?!!!!!!!!»;
$string =~ s/!{8}//;
print $string;

Здесь мы удаляем ровно 8 восклицательных знаков, поэтому результат будет такой:

It is some text?!!!!!!!!

Если мы добавим модификатор g, то и последние 8 восклицательных знаков тоже исчезнут, а
вот если сделать 9 восклицательных знаков, тогда ничего не будет заменено…
Теперь о «жадности» квантификаторов, как говорилось выше, квантификатор заменит самую
длинную серию — это и есть жадность. Разберем такой пример, вы хотите заменить «That is» на «That’s»:

# вероятно вы сделате так
$string = «That is reality, isn’t it?»;
$string =~ s/.*is/That’s/;
print $string;

Результат будет такой:

That’sn’t it?

Т.к. «жадность» квантификаторов проявляется слева направо, будет
выбрана максимальная серия слева направо. Это исправить легко — просто добавляем знак вопроса «?»:

$string =~ s/.*?is/That’s/;

И теперь результат будет тот, что нужно:

That’s reality, isn’t it?

Вопросительный знак обозначает ноль или одно совпадение, поэтому как только найдено первое
совпадение оно сразу заменяется, и все. Вот список минимальных квантификаторов: +?, *?, ??, {}?.
Дальше несколько примеров с квантификаторами.

Удаляем начальные пропуски

$string = » Some text»;
$string =~ s/^\s+//;

Удаляем конечные пропуски

$string = «Some text «;
$string =~ s/\s+$//;

А теперь классы и группы. Класс символов — это символ, или список символов заключенные в квадратные скобки. Любой
символ из квадратных скобок сопоставляется со строкой для сравнения, например:

$string = «Berry»;
if ($string =~ /[br]/){
print «B and R»;
}

В данном случае оператор m/…/ используется в скалярном контексте, поэтому в случае
совпадения шаблона возвращает истину, иначе пустую строчку. Знак дефис (-) имеет особый
смысл для класса символов — диапазон символов (в начале указывается начальный символ,
потом конечный), например:

$string = «some Text»;
if($string =~ /[A-Z]/){
print «Uppercase here…»;
}

Или вот другой пример:

# если есть буквы то возвращает истину
$string = «some text»;
if($string =~ /[A-Za-z]/){
print «Letters here…»;
}

Здесь диапазон от A до Z, заглавных букв, т.е. если в строчке есть хотя бы одна заглавная
буква, то оператор m/…/ возвращает истину. А если перед открывающей квадратной скобкой
поставить символ ^, тогда смысл меняется на противоположный, т.е. символ сравнивается,
с любым не входящим в этот класс.

(Продолжение следует)

Оставить мнение

Check Also

Почему iPhone был и будет быстрее смартфонов на Android. Колонка Олега Афонина

Почему iPhone 7 работает быстрее Samsung Galaxy S7, а iPhone 8 – быстрее Galaxy S8? В чём …