Результат выполнения одного тестового задания на Perl

Задание #1 (Perl)

Текст задания

Создать регулярное выражение, вытаскивающее дату и время. А также
комментарий, если он есть. Результат вывести на экран в отсортированном по
дате (в убывающем порядке).
Должно получиться только одно регулярное выражение, разбирающее все 3
варианта.

Входные данные (data01.txt)

Вариант 1: ^92(28/10/2002)**&[19:10:50]@Comment: Text String
Вариант 2: ^-06/02/2002*$21:55:45
Вариант 3: ^*13/08/2002*DX145&[22:50:20]@Comment: Text String

Решение

#!/usr/bin/perl -w
use strict; # Строгий синтаксис

# Получаем имя файла со стоками для парсинга из 1-го параметра командной строки
my $filename=$ARGV[0] if defined $ARGV[0] && $ARGV[0];
# По умолчанию(если в командной строке не задали) - data01.txt
$filename = "data01.txt" if !$filename;

# Открываем файл для чтения, если не открылся - заканчиваем и пишем сообщение об
# ошибке
open(A,$filename) or die $!;
print "============ ============\n";

my @list = ();
while(<A>){
    # Помещаем результат парсинга каждой строки в массив в виде хэша
    push
        @list,
        {"year",$3,"mon",$2,"day",$1,"time",$4,"comment",$6}
        if
            ~m/^
            .*[^\d](\d+)\/(\d+)\/(\d+)[^\d] (?#Вытаскиваем дату)
            .*?[^\d](\d+:\d+:\d+)[^\d]      (?#Вытаскиваем время)
            .*?(Comment:(.*)){0,1}          (?#Вытаскиваем комментарий)
            $/ix;

}

# Выводим строки в порядке убывания даты
foreach my $item
(
    sort
    { # Начало: Задаём свою функцию сравнения элементов массива
        $b->{year}.$b->{mon}.$b->{day}.$b->{"time"}
        cmp # Сравниваем как строки
        $a->{year}.$a->{mon}.$a->{day}.$a->{"time"}
    } # Конец: Задаём свою функцию сравнения элементов массива
    @list
)
{
    # NO COMMENT, если комментария нет
    $item->{comment} = "NO COMMENT" if !$item->{comment};
    # Форматированный вывод результата
    printf("%s/%s/%s %s - %s\n",
        $item->{day},$item->{mon},$item->{year},$item->{"time"},$item->{comment}
    );
}

print "============= / ============\n";
close(A) or die $!;

Задание #2 (MySQL + Perl)

Текст задания

Требуется создать базу с древовидным строением, и вывести все это одним
запросом MySQL, в виде дерева, учитывая, что в каждом разделе, может быть
сколько угодно подразделов.

Решение

Дамп БД (data02.sql)

DROP TABLE IF EXISTS `testtask_tree`;

CREATE TABLE IF NOT EXISTS `testtask_tree` (
  `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'ID раздела',
  `parent_id` int(11) UNSIGNED NOT NULL DEFAULT '0' COMMENT 'ID родительского раздела',
  `level` int(11) NOT NULL DEFAULT '0' COMMENT 'Уровень вложенности',
  `name` varchar(255) NOT NULL COMMENT 'Название раздела',
  PRIMARY KEY  (`id`),
  KEY `parent_id` (`parent_id`),
  KEY `level` (`level`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COMMENT='Разделы' AUTO_INCREMENT=12 ;

  INSERT INTO `testtask_tree` (`id`, `parent_id`, `level`, `name`) VALUES
  (1, 0, 0, 'Определения'),
  (2, 0, 0, 'Функции, использующие регулярные выражения'),
  (3, 0, 0, 'Как работают регулярные выражения'),
  (4, 1, 1, 'одиночные символы (characters)'),
  (5, 1, 1, 'классы символов (character classes)'),
  (6, 1, 1, 'квантификаторы (quantifiers)'),
  (7, 1, 1, 'мнимые символы (assertions)'),
  (8, 7, 2, '^ - начало строки текста'),
  (9, 7, 2, '$ - конец строки или позиция перед символом начала новой строки, распо-ложенного в конце'),
  (10, 2, 1, 'split'),
  (11, 2, 1, 'grep');

Perl-скрипт

#!/usr/bin/perl
use strict;
use DBI; # Подключаем модуль работы с БД

# Определяем параметры подключения к БД.
my $DB_HOST = "localhost";
my $DB_USER = "acheto";
my $DB_PASS = "zaqwedcxs";
my $DB_NAME = "acheto";
my $DB_DUMP = "data02.sql";

################### Необязательная инициализирующая часть задачи ###############
# Заливка дампа БД
my $command = "mysql -u $DB_USER -p$DB_PASS -h $DB_HOST ".
    "--default-character-set=utf8 $DB_NAME < $DB_DUMP";
`$command`;
################ Конец: Необязательная инициализирующая часть задачи ###########

# Соединяемся с СУБД
my $dba=DBI->connect("DBI:mysql:dbname=$DB_NAME:host=$DB_HOST",$DB_USER,$DB_PASS)
    or die "Cant connect to database\n";
# Выставляем кодировку соединения
$dba->do("SET NAMES 'utf8';");

my $query = "
    SELECT
        `id`,           -- ID элемента дерева
        `parent_id`,    -- ID родителя элемента дерева
        `level`,        -- Уровень вложенности элемента (этим полем мы
                        -- проигрываем в дисковом пространстве, и хлопотах по
                        -- формированию дерева, зато ускоряем процесс его вывода)
        `name`          -- Название элемента дерева
    FROM
        `testtask_tree`
";
# Отправляем запрос
my $stha = $dba->prepare($query) or die;
$stha -> execute or die;

# Вытаскиваем элементы дерева по одному, вставляя их в массив сразу за
# их родителями (функция search_index_by_id позволяет нам определить индекс
# родительского элемента в массиве по его ID)
my @tree = ();my $index = 0;
while(my @row = $stha->fetchrow_array){
    splice @tree, search_index_by_id($row[1], \@tree)+1, 0, \@row;
}

# Окончательный вывод дерева
print "=================================\n";
foreach my $row(@tree){
    print " " x 4 x @{$row}[2];
    print "* ";
    print @{$row}[3]."\n";
}
print "=============================\n";

# Отсоединяемся от СУБД
$dba->disconnect;

# Функция для нахождения индекса в массиве по ID элемента
sub search_index_by_id{
    my ($id, $array) = @_;
    return 0 if $id == 0;
    for(my $i=0;$i<scalar @{$array};$i++){
        return $i if @{@{$array}[$i]}[0] == $id;
    }
    return -1;
}

Добавить комментарий