Операторы m// и s///
4.2.2. Оператор m// в списковом контексте без модификатора g
Рассмотрим работу оператора m// в списковом контексте в режиме однократного поиска (т.е без модификатора g ). Возвращаемое значение зависит от того, есть ли в шаблоне захватывающие скобки. Если есть хотя бы одна пара захватывающих скобок, то в результате будет возвращен список из значений всех нумерованных переменных по числу использованных в регулярном выражении захватывающих скобок: ($1, $2, $3, …).
Сами эти нумерованные переменные также создаются. В этом варианте оператор m// обычно применяется, когда надо извлечь из строки заранее известное число групп переменная=значение. Например:
my $url='var1=value1&var2=value2'; my @pairs=$url =~ /(\w+)=(\w+)&(\w+)=(\w+)/; print join ',',@pairs;
На печать выйдет строка
var1,value1,var2,value2
Если в шаблоне нет захватывающих скобок, то в случае успешного поиска возвращается список из одного элемента - числа 1.
В случае неудачного поиска в обоих случаях возвращается пустой список.
Вот пример идиомы для применения оператора m// в списковом контексте:
my $date='2007/3/12'; if (my($year,$month,$day)=$date =~ m!^(\d+)/(\d+)/(\d+)$!) { print "Year=$1, month=$2, day=$3"; } else { print 'Not found!'; }
На печать выведется
Year=2007, month=3, day=12
Мы присваиваем вовращаемое значение списку, поэтому применяется списковый контекст оператора поиска. Затем в операторе if этот список рассматривается в скалярном контексте, что дает число элементов этого списка. Полученный результат используется для проверки успешности выполнения оператора поиска.
4.2.3. Оператор m// в скалярном контексте с модификатором g
Оператор поиска в скалярном контексте и с модификатором g ведет себя особым образом: переменная, к которой применяется поиск, будет неявно хранить позицию, на которой остановился последний поиск оператором m// в этой переменной. При очередном применении к этой переменной оператора поиска с модификатором g (в списковом или скалярном контексте) поиск продолжится не с начала текста, а с той позиции, на которой он остановился в последний раз. Это позволяет применить к одной и той же переменной несколько операторов поиска и извлекать из текста элементы один за другим. Эта позиция, на которой остановился оператор m//g в последний раз, может быть получена при обращении к функции pos с тем же аргументом, к которому применялся этот поиск.
Вот пример:
$_='1234567890'; /(\d)(\d)/g; print "$1,$2\n"; my @a=/(\d)(\d)/g; print join ',',@a;
На печать выйдут строки
1,2 3,4,5,6,7,8,9,0
Такая особенность сделана для возможности создания программ лексеров, которые разбирают текст на лексические единицы. Примеры мы увидим в следующих главах.
В случае применения оператора поиска к одной и той же константе:
while ('abcd'=~/(\w)/g) { print $1 }
она тоже будет хранить последнюю позицию поиска, иначе этот цикл продолжался бы вечно, каждый раз находя букву a. На печать выйдет строка
abcd
4.2.4. Оператор m// в списковом контексте с модификатором g
Если оператор поиска используется в глобальном поиске в списковом контексте и в шаблоне есть захватывающие скобки, то в случае успешного поиска возвращаются все найденные фрагменты текста. В случае неудачного поиска возвращается пустой список.
Пример:
my $text='123 234 345 456'; my @m=$text =~ /(\d+)(\s+)/g; print @m;
Будет напечатана строка
123 234 345 456
Если в регулярном выражении нет захватывающих скобок, то возвращается список всех найденных прототипов всего шаблона, как если бы весь он был заключен в круглые скобки:
my $text='123 234 345 456'; my @m=$text =~ /\d+/g; print join ',',@m;
Будет напечатано
123,234,345,456
4.2.5. Работа оператор s/// с модификатором g и без него
Оператор замены s/// без модификатора g ищет в заданной переменной прототип регулярного выражения и в случае нахождения заменяет его на выражение для замены, после чего заканчивает свою работу. При наличии модификатора g замена производится столько раз, сколько раз был найден фрагмент текста, соответствующий регулярному выражению. В результате все найденные фрагменты будут заменены на заданное выражение. В результате возвращается число произведенных замен или пустая строка (или соответствующий список в случае спискового контекста). Например:
my $text='123 234 345 456'; $text =~ s/\d+/a/; print $text;
Получим строку
a 234 345 456
Еще пример:
my $text='123 234 345 456'; $text =~ s/\d+/reverse $&/ge; print $text;
Здесь получим такой результат:
321 432 543 654
В последнем операторе поиска и замены мы использовали режим замены с модификатором e (с выполнением кода Perl ). В результате каждое найденное число заменилось на это же число, записанное в обратном порядке. Также мы могли бы написать:
$text =~ s/(\d+)/reverse $1/ge;
В операторах m// и s/// специальные переменные $1, $2, …, $&, $`, $' и т.д. для каждой итерации, обусловленной модификатором g, создаются заново (локализуются). В результате при замене используются нужные значения этих переменных, которые возникли при последней итерации поиска.