Зачистка простого текстового файла без HTML? - PullRequest
2 голосов
/ 08 декабря 2011

У меня есть следующие данные в текстовом файле:

1.  Value
Location :  Value
Owner:  Value
Architect:  Value

2.  Value
Location :  Value
Owner:  Value
Architect:  Value

... upto 200+ ...

Нумерация и слово Значение изменяются для каждого сегмента.

Теперь мне нужно вставить эти данные в базу данных MySQL.

У вас есть предложение о том, как я могу пройти и очистить его, чтобы я мог получить значение текста рядом с числом и значение "location", "owner", "architect"?

Кажется, это сложно сделать с классом очистки DOM, поскольку там нет HTML-тегов.

Ответы [ 6 ]

5 голосов
/ 08 декабря 2011

Если данные постоянно структурированы, вы можете использовать fscanf для сканирования их из файла.

/* Notice the newlines at the end! */
$format = <<<FORMAT
%d. %s
Location :  %s
Owner:  %s
Arcihtect:  %s


FORMAT;

$file = fopen('file.txt', 'r');
while ($data = fscanf($file, $format)) {
    list($number, $title, $location, $owner, $architect) = $data;
    // Insert the data to database here
}
fclose($file);

Подробнее о fscanf в документах .

4 голосов
/ 08 декабря 2011

Если каждый блок имеет одинаковую структуру, вы можете сделать это с помощью функции file(): http://nl.php.net/manual/en/function.file.php

$data = file('path/to/file.txt');

При этом каждая строка является элементом в массиве, и вы можете проходить через него.

for ($i = 0; $i<count($data); $i+=5){
    $valuerow = $data[$i];
    $locationrow = $data[$i+1];
    $ownerrow = $data[$i+2];
    $architectrow = $data[$i+3];
    // strip the data you don't want here, and instert it into the database.
}
3 голосов
/ 08 декабря 2011

Это будет работать с очень простым анализатором, ориентированным на строки.Каждую строку вы накапливаете проанализированные данные в массив ().Когда что-то говорит о том, что вы записываете новую запись, вы сбрасываете то, что проанализировали, и продолжаете снова.

Линейно-ориентированные парсеры обладают большим свойством: они требуют мало памяти и, что самое главное, постоянной памяти.Они могут обрабатывать гигабайты данных без каких-либо потов.Я управляю кучей производственных серверов, и нет ничего хуже, чем те сценарии, которые сбрасывают целые файлы в память (затем вставляют массивы с проанализированным содержимым, для которого требуется более чем вдвое больший размер исходного файла).

Это работает ив большинстве случаев неразрывно:

<?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.

2 голосов
/ 08 декабря 2011

Это даст вам то, что вы хотите,

$array = explode("\n\n", $txt);
foreach($array as $key=>$value) {
    $id_pattern = '#'.($key+1).'. (.*?)\n#';
    preg_match($id_pattern, $value, $id);

    $location_pattern = '#Location \: (.*?)\n#';
    preg_match($location_pattern, $value, $location);


    $owner_pattern = '#Owner\: (.*?)\n#';
    preg_match($owner_pattern, $value, $owner);


    $architect_pattern = '#Architect\: (.*?)#';
    preg_match($architect_pattern, $value, $architect);

    $id = $id[1];
    $location = $location[1];
    $owner = $owner[1];
    $architect = $architect[1];

    mysql_query("INSERT INTO table (id, location, owner, architect) VALUES ('".$id."', '".$location."', '".$owner."', '".$architect."')");
//Change MYSQL query

}
0 голосов
/ 08 декабря 2011
preg_match_all("/(\d+)\.(.*?)\sLocation\s*\:\s*(.*?)\sOwner\s*\:\s*(.*?)\sArchitect\s*\:\s*(.*?)\s?/i",$txt,$m);

$matched = array();

foreach($m[1] as $k => $v) {

    $matched[$v] = array(
        "location" => trim($m[2][$v]),
        "owner" => trim($m[3][$v]),
        "architect" => trim($m[4][$v])
    );

}
0 голосов
/ 08 декабря 2011

Согласовано с решением Topener, вот пример, если каждый блок состоит из 4 строк + пустая строка:

$data = file('path/to/file.txt');
$id = 0;
$parsedData = array();
foreach ($data as $n => $row) {
  if (($n % 5) == 0) $id = (int) $row[0];
  else {
    $parsedData[$id][$row[0]] = $row[1];
  }
}

Структуру будет удобно использовать для MySQL или whatelse.Я не добавил код для удаления двоеточия из первого сегмента.

Удачи!

...