PERL: БИБЛИОТЕКА ПРОГРАММИСТА - стр. 191
# Команда не работает
perl -ne 'BEGIN { $top=3; $bottom=5 } print if Stop .. $bottom' /etc/passwd
# Работает
perl -ne 'BEGIN {$top=3; $bottom=5 } \
print if $. == Stop .. $. == Sbottom' /etc/passwd
# Тоже работает
perl -ne 'print if 3 .. 5' /etc/passwd
Операторы .. и ... отличаются своим поведением в том случае, если оба операнда могут оказаться истинными в одной строке. Рассмотрим два случая:
6.8. Извлечение строк из определенного интервала 199
print if /begin/ .. /end/; print if /begin/ ... /end/;
Для строки "You may not end here you begin" оба интервальных оператора возвращают true. Однако оператор .. не будет выводить дальнейшие строки. Дело в том, что после выполнения первого условия он проверяет второе условие в той же строке; вторая проверка сообщает о найденном конце интервала. С другой стороны, оператор . . . продолжит поиск до следующей строки, в которой найдется /end/, — он никогда не проверяет оба операнда одновременно.
Разнотипные условия можно смешивать:
while (<>) { |
|||
$in_header |
= |
1 . |
. /"$/; |
$in_body |
$/ • |
. eof(); |
Переменная $in_header будет истинной, начиная с первой входной строки и заканчивая пустой строкой, отделяющей заголовок от основного текста, — например, в почтовых сообщениях, новостях Usenet и даже в заголовках HTTP (теоретически строки в заголовках HTTP должны завершаться комбинацией CR/ LF, но на практике серверы относятся к их формату весьма либерально). Переменная $in_body становится истинной в момент обнаружения первой пустой строки и до конца файла. Поскольку интервальные операторы не перепроверяют начальное условие, остальные пустые строки (например, между абзацами) игнорируются.
Рассмотрим пример. Следующий фрагмент читает файлы с почтовыми сообщениями и выводит адреса, найденные в заголовках. Каждый адрес выводится один раз. Заголовок начинается строкой "From:" и завершается первой пустой строкой. Хотя это определение и не соответствует RFC-822, оно легко формулируется.