регулярные выражения и $1
От: slava_phirsov Россия  
Дата: 07.06.10 09:52
Оценка:
Доброго времени суток всем читающим!

ActivePerl 5.8.9 Win32

Имеем вот такой пример кода:

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. Это лыжи не едут, или как?

Заранее благодарю.
Люди! Люди, смотрите, я сошел с ума! Люди! Возлюбите друг друга! (вы чувствуете, какой бред?)
perl
Re: регулярные выражения и $1
От: anonymous Россия http://denis.ibaev.name/
Дата: 07.06.10 10:53
Оценка: 7 (2)
Здравствуйте, slava_phirsov, Вы писали:

_>Имеем вот такой пример кода:

_>
_>until ($bar =~ $re)
_>{
_>    $bar .= shift @foo;
_>    print $bar . "\n";
_>}
_>

_>Выражение в цикле 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";
}
perl регулярные выражения
Re[2]: регулярные выражения и $1
От: slava_phirsov Россия  
Дата: 07.06.10 12:34
Оценка:
Здравствуйте, anonymous, Вы писали:

...

Тогда каким макаром можно провернуть такую штуку: модифицировать строку до тех пор, пока не совпадет, а после совпадения взять нужный фрагмент, захваченный "()" в $1 ? Прямолинейное решение:


my $match;
until (($bar =~ $re) and (($match = $1), 1))
{
    $bar .= foo();
}


Но как-то не очень элегантно, ИМХО.

P.S. выражение (($match = $1), 1) нужно потому, что $match может быть, ну скажем, '0', в результате операция присваивания вернет '0', и until не закончится.
Люди! Люди, смотрите, я сошел с ума! Люди! Возлюбите друг друга! (вы чувствуете, какой бред?)
Re[3]: регулярные выражения и $1
От: anonymous Россия http://denis.ibaev.name/
Дата: 07.06.10 12:49
Оценка:
Здравствуйте, slava_phirsov, Вы писали:

_>Тогда каким макаром можно провернуть такую штуку: модифицировать строку до тех пор, пока не совпадет, а после совпадения взять нужный фрагмент, захваченный "()" в $1 ? Прямолинейное решение:

_>Но как-то не очень элегантно, ИМХО.

Возможны такие варианты:
until ($bar =~ $re and defined($match = $1)) { ... }

или красивее и «правильнее»:
until (($match) = $bar =~ $re) { ... }
Re[4]: регулярные выражения и $1
От: slava_phirsov Россия  
Дата: 07.06.10 12:53
Оценка:
Здравствуйте, anonymous, Вы писали:

A>
A>until (($match) = $bar =~ $re) { ... }
A>


не прокатит, т.к. захваченное в $1 значение может быть равно, например, '0'
Люди! Люди, смотрите, я сошел с ума! Люди! Возлюбите друг друга! (вы чувствуете, какой бред?)
Re[5]: регулярные выражения и $1
От: anonymous Россия http://denis.ibaev.name/
Дата: 07.06.10 13:06
Оценка: 1 (1)
Здравствуйте, slava_phirsov, Вы писали:

A>>
A>>until (($match) = $bar =~ $re) { ... }
A>>

_>не прокатит, т.к. захваченное в $1 значение может быть равно, например, '0'

Прокатит. Результатом всего этого выражения будет размер списка, который вернёт сравнение с регулярным выражением. Это будет 0 в случае несовпадения, и положительное число в обратном случае.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.