my @foo = split'', 'foo bar buzz';
my $bar = '';
my $re = qr/(.*)u/;
until ($bar =~ $re)
{
$bar .= shift @foo;
print $bar . "\n";
}
print"\$1 is undef\n"unless defined $1;
print"\$1 is $1\n"if ($bar =~ $re);
который выводит вот что:
f
fo
foo
foo
foo b
foo ba
foo bar
foo bar
foo bar b
foo bar bu
$1 is undef
$1 is foo bar b
Выражение в цикле until совпало, но $1 осталось неопределенным ( ), однако совпадение того же самого выражения ниже нормально модифицировало $1. Это лыжи не едут, или как?
Заранее благодарю.
Люди! Люди, смотрите, я сошел с ума! Люди! Возлюбите друг друга! (вы чувствуете, какой бред?)
_>Выражение в цикле until совпало, но $1 осталось неопределенным ( ), однако совпадение того же самого выражения ниже нормально модифицировало $1. Это лыжи не едут, или как?
perldoc perlre:
The numbered match variables ($1, $2, $3, etc.) and the related punctuation set ($+, $&, $`, $', and $^N) are all dynamically scoped until the end of the enclosing block or until the next successful match, whichever comes first.
То есть происходит следующее: выражение совпадает с шаблоном, мы выходим из блока, и там, вне блока, уже совсем другая переменная $1. (На самом деле та же самая, но значения у неё уже не будет.)
Для сравнения:
until ($bar =~ $re and print($1))
{
$bar .= shift @foo;
print $bar . "\n";
}
Тогда каким макаром можно провернуть такую штуку: модифицировать строку до тех пор, пока не совпадет, а после совпадения взять нужный фрагмент, захваченный "()" в $1 ? Прямолинейное решение:
my $match;
until (($bar =~ $re) and (($match = $1), 1))
{
$bar .= foo();
}
Но как-то не очень элегантно, ИМХО.
P.S. выражение (($match = $1), 1) нужно потому, что $match может быть, ну скажем, '0', в результате операция присваивания вернет '0', и until не закончится.
Люди! Люди, смотрите, я сошел с ума! Люди! Возлюбите друг друга! (вы чувствуете, какой бред?)
Здравствуйте, slava_phirsov, Вы писали:
_>Тогда каким макаром можно провернуть такую штуку: модифицировать строку до тех пор, пока не совпадет, а после совпадения взять нужный фрагмент, захваченный "()" в $1 ? Прямолинейное решение: _>Но как-то не очень элегантно, ИМХО.
Возможны такие варианты:
until ($bar =~ $re and defined($match = $1)) { ... }
_>не прокатит, т.к. захваченное в $1 значение может быть равно, например, '0'
Прокатит. Результатом всего этого выражения будет размер списка, который вернёт сравнение с регулярным выражением. Это будет 0 в случае несовпадения, и положительное число в обратном случае.