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

$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/.../ возвращает истину. А если перед открывающей квадратной скобкой
поставить символ ^, тогда смысл меняется на противоположный, т.е. символ сравнивается,
с любым не входящим в этот класс.

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

  • Подпишись на наc в Telegram!

    Только важные новости и лучшие статьи

    Подписаться

  • Подписаться
    Уведомить о
    0 комментариев
    Межтекстовые Отзывы
    Посмотреть все комментарии