Оператор диапазона «..» в Perl

Освежая свои знания по Perl, я наткнулся на место, которое оказалось недостаточно документировано. Вернее, в английском оригинале есть нетривиальное описание, которое в русском переводе документации вообще пропущено. Речь идет о поведении оператора диапазона «..» в скалярном контексте, которое мне вроде удалось-таки расшифровать.

4_6_0

Каждый оператор диапазона «A..B» в тексте программы в скалярном контексте имеет два логических состояния - истина и ложь, в которых его значение вычисляется по-разному. 

Этот оператор обычно используется при поиске каких-либо диапазонов во входящих последовательностях строк.

Вычисляется значение этого оператора таким образом:

Состояние Значение Условие смены состояния Примечание
Ложь Пустая строка (ложь). Истинное значение операнда A меняет состояние оператора на «истина». Начальное состояние оператора B не вычисляется.
Истина Последовательное число (начиная с 1), равное тому, сколько раз подряд оператору удалось оставаться в состоянии «истина».   Истинное значение операнда Вменяет состояние оператора на «ложь» A не вычисляется.

 

 

 

 

 

ПРИМЕР 1


@lines = ( " - Foo",
"0 - Bar",
" - Faa",
"1 - Baz",
" - Quux");

foreach(@lines)
{
if (/0/ .. /1/)
{
print "$_n";
}

 

выдаст диапазон из трех строк (начиная с содержащей символ “0″, и заканчивая содержащей “1″)


0 - Bar
  - Faa
1 - Baz

Переход истина->ложь:

В момент перехода в состояние «ложь» оператор возвращает последнюю истину - число с приклееными символами “E0″ (это не влияет на числовое значение результата, но позволяет выполнить строковую проверку на E0, если нужно исключить последний элемент).

 

ПРИМЕР 2


@lines = ( " - Foo",
"0 - Bar",
" - Faa",
"1 - Baz",
" - Quux");

foreach(@lines) {

my $s= /0/ .. /1/;

if ($s){ print "$st(".int($s)."):t$_n";}
}

 

Напечатает:


1 (1): 0 - Bar
2 (2): - Faa
3E0 (3): 1 - Baz

Переход ложь->истина:

Если операнд A принял значение истина, то оператор переключается в состояние «истина» и на этой же итерации вычисляет операнд B, и если B окажется истиным, то оператор вернет последнюю истину и опять переключиться в состояние «ложь».

Чтобы избежать проверки на этом переходе правого операнда, используется оператор «» (который в остальном эквивалентен «..»).

ПРИМЕР 3

@lines = ( " - Foo",
"01 - Bar",
" - Faa",
"1 - Baz",
" - Quux");

foreach(@lines) {

my $s= /0/ .. /1/;

if ($s) { print "$s: $_n";}

 

}

 

Выдаст:


1E0: 01 - Bar

 

Но в случае


my $s= /0/.../1/;

 

 выдаст:


1: 01 - Bar
2: - Faa
3E0: 1 - Baz

Умолчания:

Если какой-то из двух операндов A или B является константой, то этот операнд будет вычисляется как истина, если он равен (как целое число) номеру текущей строки ввода ($.)

ПРИМЕР 4.


if (101 .. 200) { print; }

печатает 2-ю сотню строк, то же что


if($. == 101 .. $. == 200) { print; }

а код


next line if (1 .. /^$/);

пропустит заголовок почтового сообщения (пустая строка /^$/ значит конец заголовка) - то же, что


next line if ($. == 1 .. /^$/);

Поделиться/Сохранить

Вы должны авторизоваться, чтобы оставлять комментарии.