Это будет работать с очень простым анализатором, ориентированным на строки.Каждую строку вы накапливаете проанализированные данные в массив ().Когда что-то говорит о том, что вы записываете новую запись, вы сбрасываете то, что проанализировали, и продолжаете снова.
Линейно-ориентированные парсеры обладают большим свойством: они требуют мало памяти и, что самое главное, постоянной памяти.Они могут обрабатывать гигабайты данных без каких-либо потов.Я управляю кучей производственных серверов, и нет ничего хуже, чем те сценарии, которые сбрасывают целые файлы в память (затем вставляют массивы с проанализированным содержимым, для которого требуется более чем вдвое больший размер исходного файла).
Это работает ив большинстве случаев неразрывно:
<?php
$in_name = 'in.txt';
$in = fopen($in_name, 'r') or die();
function dump_record($r) {
print_r($r);
}
$current = array();
while ($line = fgets($in)) {
/* Skip empty lines (any number of whitespaces is 'empty' */
if (preg_match('/^\s*$/', $line)) continue;
/* Search for '123. <value> ' stanzas */
if (preg_match('/^(\d+)\.\s+(.*)\s*$/', $line, $start)) {
/* If we already parsed a record, this is the time to dump it */
if (!empty($current)) dump_record($current);
/* Let's start the new record */
$current = array( 'id' => $start[1] );
}
else if (preg_match('/^(.*):\s+(.*)\s*/', $line, $keyval)) {
/* Otherwise parse a plain 'key: value' stanza */
$current[ $keyval[1] ] = $keyval[2];
}
else {
error_log("parsing error: '$line'");
}
}
/* Don't forget to dump the last parsed record, situation
* we only detect at EOF (end of file) */
if (!empty($current)) dump_record($current);
fclose($in);
?>
Очевидно, что в function dump_record
вам понадобится что-то подходящее на ваш вкус, например, печать правильно отформатированного оператора SQL INSERT.