Существует база данных о бот-информации, которую я хотел бы проанализировать. Говорят, что он похож на сообщения RFC822 .
Прежде чем я заново изобрел колесо и написал собственный синтаксический анализатор, я подумал, что увижу, есть ли что-то еще. Я наткнулся на imap_rfc822_parse_headers()
, который, похоже, делает именно то, что я хочу. К сожалению, расширение IMAP недоступно в моей среде.
Я видел много альтернатив в Интернете и в Stack Overflow. К сожалению, все они созданы для электронной почты и делают больше, чем мне нужно … часто разыгрывая целые сообщения электронной почты и обработки заголовков особыми способами. Я просто хочу просто проанализировать эти заголовки в полезный объект или массив.
Есть ли прямая версия PHP imap_rfc822_parse_headers()
, или что-то эквивалентное, которое будет анализировать такие данные? Если нет, я напишу свое.
robot-id: abcdatos robot-name: ABCdatos BotLink robot-from: no robot-useragent: ABCdatos BotLink/1.0.2 (test links) robot-language: basic robot-description: This robot is used to verify availability of the ABCdatos directory entries (http://www.abcdatos.com), checking HTTP HEAD. Robot runs twice a week. Under HTTP 5xx error responses or unable to connect, it repeats verification some hours later, verifiying if that was a temporary situation. robot-history: This robot was developed by ABCdatos team to help working in the directory maintenance. robot-environment: commercial modified-date: Thu, 29 May 2003 01:00:00 GMT modified-by: ABCdatos robot-id: acme-spider robot-name: Acme.Spider robot-cover-url: http://www.acme.com/java/software/Acme.Spider.html robot-exclusion: yes robot-exclusion-useragent: Due to a deficiency in Java it's not currently possible to set the User-Agent. robot-noindex: no robot-host: * robot-language: java robot-description: A Java utility class for writing your own robots. robot-history: robot-environment: modified-date: Wed, 04 Dec 1996 21:30:11 GMT modified-by: Jef Poskanzer ...
Предполагая, что $data
содержит образцы данных, которые вы вставили выше, вот синтаксический анализатор:
<?php /* * $data = <<<'DATA' * <put-sample-data-here> * DATA; * */ $parsed = array(); $blocks = preg_split('/\n\n/', $data); $lines = array(); $matches = array(); foreach ($blocks as $i => $block) { $parsed[$i] = array(); $lines = preg_split('/\n(([\w.-]+)\: *((.*\n\s+.+)+|(.*(?:\n))|(.*))?)/', $block, -1, PREG_SPLIT_DELIM_CAPTURE); foreach ($lines as $line) { if(preg_match('/^\n?([\w.-]+)\: *((.*\n\s+.+)+|(.*(?:\n))|(.*))?$/', $line, $matches)) { $parsed[$i][$matches[1]] = preg_replace('/\n +/', ' ', trim($matches[2])); } } } print_r($parsed);
Тип сообщения MIME довольно распространен. Парсеров существует много, но обычно трудно рекламировать. Лично я прибегаю к регулярному выражению здесь, если формат несколько согласован.
Например, эти двое сделают трюк:
// matches a consecutive RFC821 style key:value list define("RX_RFC821_BLOCK", b"/(?:^\w[\w.-]*\w:.*\R(?:^[ \t].*\R)*)++\R*/m"); // break up Key: value lines define("RX_RFC821_SPLIT", b"/^(\w+(?:[-.]?\w+)*)\s*:\s*(.*\n(?:^[ \t].*\n)*)/m");
Номер один разрывает согласованные блоки сообщений / * линий, а второй может быть использован для разделения каждого такого блока. Ему нужна пост-обработка, чтобы стянуть ведущий вывод из строк непрерывных значений.