Есть текст, в котором нужно выделить все совпадения с вот таким шаблоном "aaa(.+?)bbb(.+?)ccc" и распечатать $1/$2 соответственно. Так вот почему если сделать так:
@Links = $TMP=~/aaa(.+?)bbb(.+?)ccc/g;
join("\n",@Links);
то всё нормально, а если сразу, без перехода к массиву, т.е. вот так:
foreach ($TMP=~/aaa(.+?)bbb(.+?)ccc/g)
{
print $1."\n".$2."\n";
}
то распечатается одно и тоже (последнее) совпадение с шаблоном столько раз, сколько совпадение найдено.
Я понимаю, что в случае foreach, видимо, каждый раз выполняется сопоставление и печатается одно и тоже, но не пойму логику работы перла в случае перехода к массиву. Ведь модификатор /g есть и там и там..
Здравствуйте, <Аноним>, Вы писали:
А>А> foreach ($TMP=~/aaa(.+?)bbb(.+?)ccc/g)
А> {
А> print $1."\n".$2."\n";
А> }
А>
1) (m//) вернет list
2) по результатам работы m// будут выставлены $1 и $2 — в последний матч
3) foreach распечатает их столько раз, сколько будет элементов листе — по количеству матчей.
Используйте $_ или замените foreach на while.
perlsyn:
LABEL foreach VAR (LIST) BLOCK
...
The "foreach" loop iterates over a normal list value and sets the vari-
able VAR to be each element of the list in turn.
...
"for" comes more naturally.) If VAR is omitted, "$_" is set to each
value.
Здравствуйте, Аноним, Вы писали:
А>Есть текст, в котором нужно выделить все совпадения с вот таким шаблоном "aaa(.+?)bbb(.+?)ccc" и распечатать $1/$2 соответственно. Так вот почему если сделать так:
А>А> @Links = $TMP=~/aaa(.+?)bbb(.+?)ccc/g;
А> join("\n",@Links);
А>
А>то всё нормально, а если сразу, без перехода к массиву, т.е. вот так:
А>А> foreach ($TMP=~/aaa(.+?)bbb(.+?)ccc/g)
А> {
А> print $1."\n".$2."\n";
А> }
А>
А>то распечатается одно и тоже (последнее) совпадение с шаблоном столько раз, сколько совпадение найдено.
А>Я понимаю, что в случае foreach, видимо, каждый раз выполняется сопоставление и печатается одно и тоже, но не пойму логику работы перла в случае перехода к массиву. Ведь модификатор /g есть и там и там..
Второй вариант(скалярный контекст) надо писать так:
while ($TMP=~/aaa(.+?)bbb(.+?)ccc/g)
{
print $1."\n".$2."\n";
}
В случае foreach (...) мы вроде ожидаем контекст массива. Поэтому мы сразу получаем массив и естественно что в $1 и $2 результаты последнего совпадения — их мы и печатаем каждый раз.