Регулярные выражения Perl и их применение
ba2f5a3f

Поиск n-ного совпадения


С модификатором g происходит поиск всех прототипов шаблона, но что делать, если нужно только вполне определенное, скажем, третье, совпадение? Здесь можно применить оператор цикла while:

use locale;

my $s='Тел. 2-3344. Другой тел. 3-2233, а вот еще один тел. 4-1122'; my $count=0; while ($s =~ /тел\.\s+([\d-]+)/gi) { if (++$count == 3) { print "Третий номер: $1\n"; } }

На печать выйдет строка

Третий номер: 4-1122

В регулярном выражении мы захватываем в переменную $1 последовательность из цифр и знака минус, которая стоит после фрагмента "тел. ". Модификатор g обеспечивает поиск всех прототипов шаблона друг за другом, сохраняя в переменной $s смещение конца предыдущего совпадения. При очередном успехе оператор поиска возвращает единицу, что заставляет цикл while продолжать работать. После того, как будет найден последний номер телефона, оператор поиска вернет пустую строку, и оператор while закончит выполнение. Также можно было бы после печати третьего телефона поставить оператор last.

Модификатор i нужен, т.к. не все фрагменты "тел." набраны строчными буквами. Но тогда нужна русская локаль, чтобы модификатор i действовал также на русские буквы.

Иначе в этом примере совпадение начнется со второго телефонного номера и на печать ничего не выйдет.

С таким же успехом можно было использовать цикл for:

use locale;

my $s='Тел. 2-3344. Другой тел. 3-2233, а вот еще один тел. 4-1122'; for (my $count=0; $s =~ /тел\.\s+([\d-]+)/gi;) { if (++$count == 3) { print "Третий номер: $1\n"; last; } }

Наконец, можно использовать встроенный код Perl, но тогда надо форсировать списочный контекст выполнения оператора поиска, чтобы поиск выполнялся итеративно под действием модификатора g, иначе после нахождения первого телефона поиск закончится:

use locale;

my $s='Тел. 2-3344. Другой тел. 3-2233, а вот еще один тел. 4-1122'; my $count=0; my @a=$s =~ /тел\.\s+([\d-]+) (?{ if (++$count == 3) { print "Третий номер: $1\n"; } })/gix;

Это, конечно, не так красиво из-за того, что пришлось присваивать все найденные телефоны массиву.



Содержание раздела