LXF70:Perl. Сортируем наш код
|
|
|
Часть 2. Напуганы непостижимыми операторами Perl и регулярными выражениями? Еще больше напуганы словом «непостижимые»? Марк Фиоретти (Marco Fioretti) может всё объяснить!
Содержание |
Перед тем, как отправиться в путешествие по королевству Perl, вы должны запомнить три типа переменных: скаляр, массив и хэш. Отмеченные символом $ скаляры содержат один кусочек информации, например строку. В нашем втором руководстве мы узнаем, как работать с более сложными величинами, массивами и хэшами, а затем покажем вам настоящую черную магию Perl — регулярные выражения.
Сортировка и перечисление
Вы помните, как массивы упорядочивают скаляры? Оператор списка Perl действует похожим образом. Это безымянная последовательность скаляров в круглых скобках. Хорошими вариантами использования оператора списка является присвоение значений двум или более переменным в одной инструкции или обмен значениями переменных тем или иным способом.
($X,$Y,$Z) = ($Y,$Z,$X); # Circular shift ($Name,$Surname,$Phone) = ('John', 'Smith',5556791); ($DARTH_VADER,@JEDI) = ('Anakin Skywalker', 'Yoda', 'Obi-Wan', 'Mace Windu');
Две первые строчки говорят сами за себя. В третьей строки список из левой части присваивания состоит из скаляра ($DARTH_VaDer) и именованного массива (@JEDI). Все знают, что случится после такого присвоения: на Тёмную Сторону Силы юный Энакин перейдёт в одиночестве. И поскольку вторым элементом списка является массив @JEDI, все остальные рыцари из правой части выражения попадут в него, в том же самом порядке.
Давайте теперь посмотрим на функцию splice(), которая используется для удаления, добавления или замены элементов массива. Для начала определим несколько планет:
@STAR_WARS_PLANETS = ('Naboo', 'Tatooine', 'Geonosis');
Используем splice() для того, чтобы добавить Coruscant и Alderaan сразу после Tatooine:
splice (@STAR_WARS_PLANETS, 2,0, ('Coruscant', 'Alderaan'));
Первым аргументом этой функции является имя массива, STAR_WARS_PLANETS. Затем идёт индекс элемента (считая с нуля!), с которого мы хотим начать склейку, в нашем случае это Tatooine. Третьим параметром является число элементов для удаления. Сейчас мы не хотим ничего удалять, нам надо только добавить несколько планет, поэтому в качестве третьего параметра передается «0». Последний, необязательный элемент — это список, который будет добавлен в позицию, номер которой вы только что указали. Если этот агрумента не указан, то splice() не добавит в массив ничего.
Если вы хотите упорядочить содержимое массива в алфавитном порядке, то вам понадобится функция sort(). По умолчанию она рассматривает содержимое переданного массива как строки, даже если там содержатся числа. Например, если вы введёте в командной строке следующее выражение:
perl -e "@A_LIST = ('Dominions', 180, 3, '10, Downing St.','Admiralty'); \ print join( \"\n\", sort @A_LIST), \"\n\";"
то получите отсортированный по алфавиту список:
10, Downing St. 180 3 Admiralty Dominions
Однако функция sort() может руководствоваться и другими критериями:
@SORTED_LIST = sort AS_I_WANT @UNORDERED_LIST;
AS_I_WANT — это функция, принимающая два скаляра в качестве аргументов и возвращающая −1, 0 или 1 в зависимости от того, какой параметр оказался меньше согласно вашему критерию. Мы рассмотрим такие функции в последующих выпусках.
Последнее замечание про массивы. Есть одна вещь, без которой не может жить ни один Perl-хакер, хотя она вовсе не выглядит как массив. Я говорю о нашем возлюбленном STDIN, стандартном потоке ввода любой «правильной» Unix-программы. К счастью, им очень просто пользоваться. Я упомянул здесь STDIN потому, что он может быть превращен в массив одним мановением руки:
@LINES = <STDIN>;
Вот так, одной единственной инструкцией вы внесли каждую строчку ввода в отдельный элемент массива @LINES. Удобно, не правда ли?
Чистый хэш
...
Регулярные выражения
...
Подсказка
Подсчёт числа элементов массива
Как можно узнать, сколько элементов содержится в массиве или хэше? Очень просто, присвоить их скалярной переменной! Поскольку она может содержать только одно число, Perl поместит туда число элементов массива. Тот же способ работает с хэшами. Функция keys возвращает массив, содержащий только ключи хэша, так что его размер можно узнать следующим образом:
$HOW_MANY_JEDI = @JEDI; $HOW_MANY_ITEMS_INTO_AN_HASH = keys %SOME_HASH;
Как разрушить свою жизнь регулярными выражениями
Perl, вероятно, содержит гораздо больше регулярных выражений, чем все другие языки программирования. Для того, чтобы своими глазами увидеть, насколько мощными и неудобными они могут быть, посмотрите на самое длинное из всех, что я видел — http://www.ex-parrot.com/~pdw/Mail-RFC822-Address.html. Говорят, что оно проверяет правильность адреса e-mail, но я не могу это проверить. Если хотите научиться создавать такие же, прочитайте книгу Джефри Фридла «Регулярные выражения» (Jeffrey Friedl, «Mastering Regular expressions», O’Reilly, 2002).
Регулярные выражения: шпаргалка
Здесь приведён список основных метасимволов, используемых в регулярных выражениях Perl. Скопируйте его и держите поближе к клавиатуре, он действительно помогает сэкономить время.
- . — Любой символ за исключением перевода строки
- ^ — Начало строки
- $ — Конец строки
- * — Ноль или более предыдущих символов
- + — Один или более предыдущий символ
- ? — Ноль или один предыдущий символ
- \n — Перевод строки
- \t — Табуляция
- \w — Числа и алфавитные символы, вне зависимости от регистра
- \W — Все символы, кроме букв или цифр
- \d — Старые добрые цифры: 0, 1 и так до 9.
- \D — Всё, кроме цифр.
- \s — Пробельные символы: пробел, табуляция, перевод строки.
- \S — Любой не пробельный символ.
- \b — Граница слова.
- | — Выбор из двух вариантов (например A|B).
- [] — Квадратные скобки определяют диапазон символов.
- () — Круглые скобки сохраняют соответствующую им подстроку.
Примечания: Когда вам необходимо вставить в регулярное выражение один из этих символов в его буквальном смысле, например знак «+», нужно поставить перед ним обратную косую черту (\).
A+ # Одна или несколько букв A \+ # один знак "+" \++ # Один или несколько знаков "+"