Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > PHP: Тексты > [PCRE] log-файл в массив


Автор: Gold Dragon 17.1.2007, 11:58
Помогите log-файл загнать в массив. Вот пример

Код

2007-01-17 09:44:20   3 11 1  GET forum.joom.ru 213.135.140.35:1127 213.85.145.245:80 1130 12371
2007-01-17 09:44:20   3 11 1  GET counter.yadro.ru 213.135.140.35:1131 88.212.196.77:80 1238 884
2007-01-17 09:44:20   3 11 1  GET forum.joom.ru 213.135.140.35:1128 213.85.145.245:80 1128 623
2007-01-17 09:44:52   3 11 3  GET vingrad.ru 213.135.140.35:1134 62.75.204.171:80 980 1384


Данные разделяются пробелами. Количество пробелов между данными не постоянно.

формат массива такой:

Код

$log = Array (
    'data',
    'time',
    'idF',
    'tHTTP',
    'sHTTP',
    'mHTTP',
    'name',
    'kIP',
    'sIP',
    'out',
    'in');

    
И уж заодно, как лучше загружать log-файл, т.к. размер его может быть довольно большим

Автор: SamDark 17.1.2007, 12:08
Gold Dragon, 
т.к. число пробелов не постояноо: используй preg_split(' +', $log_line).

Вывод лучше организовать постраничный. При этом не читать весь файл. Пользоваться fseek().

Автор: Mal Hack 17.1.2007, 14:33
Проще сначала грохнуть все двойные пробелы, затем explode.

Автор: SamDark 17.1.2007, 15:56
Mal Hack, 
Двойные пробелы всё-равно грохать регуляркой (может их и не два). Зачем делать лишние действия?

Автор: Mal Hack 18.1.2007, 01:12
А потому, что регурялка скорее всего в данном случае больше скушает.

Автор: SamDark 18.1.2007, 09:11
Mal Hack, 
Надо проверить.

Автор: Gold Dragon 18.1.2007, 12:22
Так. а как мне грухнуть двоуные, тройные и тому подобные пробулы?

Автор: mishaSL 18.1.2007, 15:07
Проще как говорил 
SamDark, к примеру preg_split("/[\s]+/", $line); потом протестируй на больших файлах.

Автор: Gold Dragon 18.1.2007, 16:06
Цитата(SamDark @  17.1.2007,  12:08 Найти цитируемый пост)
Вывод лучше организовать постраничный. При этом не читать весь файл. Пользоваться fseek().
 не понял, а как сделать постранично из файла.. Разве  fseek() работает не с бинарным файлом? Там вроде смещение в байтах..

Автор: SamDark 18.1.2007, 16:18
Gold Dragon, 
Всё правильно. Читать придётся побайтно порциями.

Автор: Mal Hack 18.1.2007, 16:23
На счет начального "гроханья" двойных пробелов я поспешил... Виноват...
Код

<?php

    $str =<<<OEF
2007-01-17 09:44:20   3 11 1             GET forum.joom.ru 213.135.140.35:1127 213.85.145.245:80 1130 12371
2007-01-17 09:44:20   3 11 1  GET counter.yadro.ru 213.135.140.35:1131 88.212.196.77:80 1238 884
2007-01-17 09:44:20   3 11 1  GET forum.joom.ru 213.135.140.35:1128 213.85.145.245:80 1128 623
2007-01-17 09:44:52   3 11 3  GET vingrad.ru 213.135.140.35:1134 62.75.204.171:80 980 1384
OEF;

    $str = preg_replace("#\s{2,}#", " ", $str);   
    
    $ar2 = preg_split("#\s|$#", $str);
    
    print_r($ar2);

?>

На выходе получаем единый вектор. Работать проще, чем с матрицей. Надо просто смещение указывать.
А смысл использовать fseek? - Никакого. Файл в любом случае будет полностью записан в ОП. Так что на больших файлам вообще потоке придется использовать.

Автор: SamDark 18.1.2007, 16:28
Mal Hack, 
Может сразу preg_split("#\s+#", $str)?
Код

<?php

    $str =<<<OEF
2007-01-17 09:44:20   3 11 1             GET forum.joom.ru 213.135.140.35:1127 213.85.145.245:80 1130 12371
2007-01-17 09:44:20   3 11 1  GET counter.yadro.ru 213.135.140.35:1131 88.212.196.77:80 1238 884
2007-01-17 09:44:20   3 11 1  GET forum.joom.ru 213.135.140.35:1128 213.85.145.245:80 1128 623
2007-01-17 09:44:52   3 11 3  GET vingrad.ru 213.135.140.35:1134 62.75.204.171:80 980 1384
OEF;  
    
    $ar2 = preg_split("#\s+#", $str);    
    print nl2br(print_r($ar2, true));

?>

Автор: Mal Hack 18.1.2007, 16:32
Цитата(SamDark @  18.1.2007,  16:28 Найти цитируемый пост)
Может сразу preg_split("#\s+#", $str)?

Наверное, это уже замашки сишника с паскальщиком smile Там сначала удаляешь, потом режешьsmile
Только не забудь, что нам еще резать надо по концу строки.


Цитата(SamDark @  18.1.2007,  16:28 Найти цитируемый пост)
print nl2br(print_r($ar2, true));

Жжошьsmile

Автор: Gold Dragon 18.1.2007, 16:39
Цитата(SamDark @  18.1.2007,  16:18 Найти цитируемый пост)
Всё правильно. Читать придётся побайтно порциями.

да но в каждой строе разное количество байт

Добавлено @ 16:51 
Цитата(Mal Hack @  18.1.2007,  16:23 Найти цитируемый пост)
На выходе получаем единый вектор. Работать проще, чем с матрицей. Надо просто смещение указывать.

По моему с матрицей лучше smile Но у тебя всё отлично работает..

SamDark, что-то не хочет запускаться...


ps
а такой глупый вопрос: пробел и табуляция - это ведь разные вещи? 

Автор: SamDark 19.1.2007, 10:22
Mal Hack, 
Цитата
Только не забудь, что нам еще резать надо по концу строки.

Ну, это же вариант с вектором... так что не надо.

Цитата
Жжошь

Люблю, когда наглядно  smile 

Gold Dragon, 
Цитата
да но в каждой строе разное количество байт

Открываешь файл. Смещаешь курсор на некоторое значение. Читаешь не менее N символов до следующего перевода строки.

Цитата
а такой глупый вопрос: пробел и табуляция - это ведь разные вещи? 

Разные, поэтому в регулярном выражении используется класс \s, который включает и пробелы и табуляции и, если не ошибаюсь, переводы строк.

Вот рабочий код для вектора:
Код

<?php

    $str =<<<OEF
2007-01-17 09:44:20   3 11 1             GET forum.joom.ru 213.135.140.35:1127 213.85.145.245:80 1130 12371
2007-01-17 09:44:20   3 11 1  GET counter.yadro.ru 213.135.140.35:1131 88.212.196.77:80 1238 884
2007-01-17 09:44:20   3 11 1  GET forum.joom.ru 213.135.140.35:1128 213.85.145.245:80 1128 623
2007-01-17 09:44:52   3 11 3  GET vingrad.ru 213.135.140.35:1134 62.75.204.171:80 980 1384
OEF;

    $ar2 = preg_split("~\s+~", $str);    
    print nl2br(print_r($ar2, true));

?>

Автор: Gold Dragon 19.1.2007, 11:50
Всё, спасибо всем! Вопрос решён

Автор: Mal Hack 19.1.2007, 15:13
Цитата(SamDark @  19.1.2007,  10:22 Найти цитируемый пост)
Ну, это же вариант с вектором... так что не надо.

Хм... А у тебя тогда получится что-то вроде: "aasd\n123"


Цитата(SamDark @  19.1.2007,  10:22 Найти цитируемый пост)
Разные, поэтому в регулярном выражении используется класс \s, который включает и пробелы и табуляции и, если не ошибаюсь, переводы строк.

Он включает в себя ТОЛЬКО пробел. Табуляция - \t


Автор: SamDark 19.1.2007, 15:22
Mal Hack, 
Из доков PHP:
Цитата

По умолчанию пробельными символами являются все символы, распознаваемые библиотечной функцией языка Си isspace(). Это позволяет собрать PCRE библиотеку с произвольными символьными наборами. В стандартной поставке функция isspace() определяет как пробельные следующие символы: пробел, разрыв страницы, начло строки, перевод каретки, горизонтальную и вертикальную табуляцию. Начиная с версии Perl 5.002, символ вертикальной табуляции \v не является пробельным и, соответственно, не соответствует классу символов \s. 

Автор: Mal Hack 19.1.2007, 15:26
Хм... Пропустил. Спасибо.

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