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


Автор: zyxerr 30.10.2008, 17:24
у меня есть файл IN.txt:
.
текст
текст
КОМАНДА ЗНАЧЕНИЕ
текст
текст
КОМАНДА ЗНАЧЕНИЕ
текст
.
этот файл размером несколько гигабайт, всего более сотни видов команд. Необходимо создать скрипт, который:
1) проверяет правильное ли значение у конкретной команды
2) если значение неправильное, то поменять на значение по-умолчанию
.
Я создал файл SPEC.txt:
.
ПАТТЕРН КОМАНДЫ,ПАТТЕРН ЗНАЧЕНИЯ,ЗНАЧЕНИЕ ПО-УМОЛЧАНИЮ
ПАТТЕРН КОМАНДЫ,ПАТТЕРН ЗНАЧЕНИЯ,ЗНАЧЕНИЕ ПО-УМОЛЧАНИЮ
ПАТТЕРН КОМАНДЫ,ПАТТЕРН ЗНАЧЕНИЯ,ЗНАЧЕНИЕ ПО-УМОЛЧАНИЮ
ПАТТЕРН КОМАНДЫ,ПАТТЕРН ЗНАЧЕНИЯ,ЗНАЧЕНИЕ ПО-УМОЛЧАНИЮ
.
в нем через запятую записан паттерн команды, паттерн значения и значение по-умолчанию.
Теперь мне нужно, пробегая по каждой строке файла IN:
1) искать паттерн команды
2) проверять правильный ли паттерн значения
3) если неправильный, то поменять на значение по-умолчанию.
.
я немного не понимаю, как лучше это сделать? Занести в хеш данные из SPEC и потом сверять с хешем, или лучше в массив и потом перебирать по индексам массива. В файле SPEC 100 строк, в файле IN - несколько миллионов. Заранее спасибо за подсказку

Автор: IceSunrise 30.10.2008, 17:46
Привет, zyxerr!

Если список команд и значений небольшой, то я не делал бы их шаблоны, а просто загнал бы все в трехуровневый хеш:

Пример:
команда_1->значение_1->значение_по_умолчанию_1
                 ->значение_2->значение_по_умолчанию_2
...

Если наборы значений для команд или наборы значений по умолчанию для значений пересекаются, то можно сделать независимые хеши с уникальными значениями и правильно расставить ссылки, это позволит съэкономить память.

Пример:
команда_1->значение_1->значение_по_умолчанию_1
                 ->значение_2->значение_по_умолчанию_2

команда_2->ссылка_на_значение_1
                  ->значение_3->ссылка_на_значение_по_умолчанию_2
...


Ну а если хочешь использовать шаблоны, то в качестве ключей хеша можно использовать рег.выраж, которые будут определять классы команд, значений и значений по умолчанию... Но тогда придется перебирать ключи, до обнаружения совпадения для перехода на следующий уровень...

Первое, что пришло на ум smile

Автор: zyxerr 30.10.2008, 18:03
Вечер добрый!

У каждой команды могут быть разные значения, но эти значения можно описать одним шаблоном.
.
пример:
!NUM 235-П
где:
!NUM - команда
235-П - значение
шаблоны:
!NUM  -шаблон команды
(\d+)-?[ПпРрЗз]? - шаблон значения
.
по-умолчанию значение = "ОШИБКА"
.
в файле SPEC у меня записано:
!NUM,(\d+)-?[ПпРрЗз]?,ОШИБКА
.
соответственно, если в тексте будет запись:
!NUM 235x
то оно не соответсвует шаблону значения и строка должна поменяться на
!NUM ОШИБКА
.

Автор: ginnie 30.10.2008, 18:52
Уважаемый zyxerr, если в SPEC.txt у Вас хранится шаблон команды, как Вы предполагаете использовать хэш?
Получается только массив. Массив массивов или хэшей - это как Вам удобнее, разница не столь значительна. Шаблоны в массиве лучше хранить в скомпилированном виде (через qr{}).

Автор: Itsys 30.10.2008, 18:58
Как вариант, можно использовать три регулярки:
Код

s/^\!(NUM\s(\d+)-?[ПпРрЗз]?)$/+$1/g

после этого
Код

s/^!NUM\s(.*)$/!NUM\sОШИБКА/g

Код

s/^\+(NUM\s(\d+)-?[ПпРрЗз]?)$/!$1/g

Автор: ginnie 30.10.2008, 20:18
Itsys, какие достоинства этого варианта, кроме усложнения?  smile 

Автор: Itsys 30.10.2008, 21:28
Надо проверить что будет работать быстрее, использование трех регулярок для всего файла или перебор по строкам...

Автор: ginnie 30.10.2008, 22:26
Itsys, как будем обрабатывать файл из нескольких миллионов строк? в память загрузим?
Регулярных выражений не 3, а 300.  smile 

Автор: Itsys 31.10.2008, 00:24
ginnie, да, наверное лучше каждую из нескольких милионов строк проверять по 100 раз.....  smile 

ЗЫ А файл можно и в память загрузить.... все зависит от объема строки... если этот файл помещается на диске, и есть место куда можно свопиться..... не вижу никакой проблемы. Мы же не знаем всех параметров задачи (размер файла, мож там размер одной строки 10-20 байт) и конфигурации компьютера (сервера) на котором эта операция будет производиться.

Автор: zyxerr 31.10.2008, 11:05
Условия такие: 
.
файл IN размером 1.5GB, длина строки - от 40 до 180 символов (стандарт - 75), всего - 26 млн строк
команд - около сотни. Каждая команда начинается с со знака "!" в начале строки (!КОМАНДА)
машина: Pentium E4600, 3 Gb оперативки, винчестер 320 GB




Автор: ginnie 31.10.2008, 12:25
zyxerr, лучше еще добавить до поиска в строке команд по шаблону проверку на "!" для ускорения. Также, если много одинаковых команд, можно добавить кэширование уже обработанных комманд в хеше и сначала проверять по нему.

Автор: zyxerr 31.10.2008, 13:13
ginnie, 
да, я уже заметил, что если начала искать /^!/ а потом уточнять /команда/, то поиск в несколько раз быстрее проходит. А можешь подсказать:по оптимизации регулярных выражений кроме книги Фридла что еще можно посмотреть? какие-нибудь познавательные блоги, форумы?

Автор: ginnie 31.10.2008, 13:26
zyxerr, по регулярным выражениям особо ничего подсказать не могу, для меня очень полезной оказалась глава "Поиск по шаблону" из книги Ларри Уолл, Том Кристиансен, Джон Орвант. Программирование на Perl. Еще очень полезно разобраться с отладочной информацией, которую выдает http://search.cpan.org/~rgarcia/perl-5.10.0/pod/perldebguts.pod#Debugging_regular_expressions.

Автор: zyxerr 31.10.2008, 13:35
ginnie, спасибо

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