Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Perl: Регулярные выражения > Вложенные скобки?


Автор: JavaCraft 8.11.2010, 14:30
Интересует общий принцип работы с повторяющимися структурами данных. Например, многострочными логами.
Допустим, дан файл 10Гб с повторяющейся структурой:

structname {
  field1 = v1
  field2 = v2
  field3 = v3
  ...
}

Читаем из него очередной кусок текста 2M в буфер $buf
Применяем один раз регулярку, которая выполняет разбор этого буфера
Обрабатываем готовый результат в цикле:
...
foo($buf);
...
sub foo{
 ?
 $rec_list = shift _
 ?
 foreach $rec (?){
   в $rec должен быть кортеж (v1,v2,v3 ...)
   передаем кортеж в другую функцию для асинхронной вставки в базу данных.
 }
}

1) Как реализовать такую регулярку?
2) Если это не оптимально, каков оптимальный алгоритм разбора таких логов на Perl?

Автор: DurRandir 8.11.2010, 18:30
Вы даже примера кусочка лога не дали, а уже хотите регулярку, которая бы его разбирала.

Автор: JavaCraft 8.11.2010, 20:55
Почему не дал? От переименования смысл не меняется.


начало буфера - обрыв структуры
"
object {
  id = 123
  name = Смартфон1
  cost = 123
  note = Почти новый
}

object {
  id = 124
  name = Смартфон2
  cost = 1234
  note = Новый новый,
новее не бывает
}

object {
  id = 125
  name = Смартфон3
  cost = 12
  note = серый, китайский,
с очень узким дисплеем
}

object {
 id "обрыв структуры

Автор: ming 12.11.2010, 18:18
непонятно зачем читать кусками по 10М, почему нельзя читать поэлементно?

Код

use strict;

read_log();

sub read_log {
    local $/ = "}";  # читать не построчно, а блоками, оканчивающимися символом }

    while(<DATA>) {    
        if (/(.+?){\s*id =(.+?)name =(.+?)cost =(.+?)note =(.+?)}/s) 
        {        
            my ($struct, $id, $name, $cost, $note) = map { trim($_) } ($1,$2,$3,$4,$5);        
            db_insert( [ $struct, $id, $name, $cost, $note ] );
        }    
    }
}

sub db_insert {    
    my $tuple = shift;
    print "Inserting " . join ', ', @$tuple;
    print "\n";
}

sub trim {
    my $str = shift;    
    $str =~ s/^\s+//;
    $str =~ s/\s+$//;
    return $str;
}

__DATA__
object {
  id = 123
  name = Смартфон1
  cost = 123
  note = Почти новый
}

object {
  id = 124
  name = Смартфон2
  cost = 1234
  note = Новый новый,
новее не бывает
}

object {
  id = 125
  name = Смартфон3
  cost = 12
  note = серый, китайский,
с очень узким дисплеем
}

Автор: Logo 16.11.2010, 17:56
А где вложенные скобки?

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)