Создание массива данных из текстового файла с элементами, разделенными хеш-символами / фунтами в PHP - PullRequest
0 голосов
/ 04 декабря 2009

У меня есть данные прогноза погоды, отформатированные так: LOC_ID # место # состояние # forecast_date # issue_date # issue_time # min_0 # max_0 # min_1 # max_1 # min_2 # max_2 # min_3 # max_3 # min_4 # max_4 # min_5 # max_5 # min_6 # max_6 # min_7 # max_7 # forecast_0 # forecast_1 # forecast_2 # forecast_3 # forecast_4 # forecast_5 # forecast_6 # forecast_7 # 090180 # Вход Эйри # VIC # 20091204 # 20091204 # 161830 ### 12 # 19 # 12 # 21 # 12 # 19 # 12 # 17 # 11 # 20 # 12 # 20 # 11 # 17 # В основном ясно. # Душ или два . # Легкий душ или два. # Душ или два. # Дождь. Ветрено. # Душ или два. Windy. # Дождь. Ветрено. Мало ливней. 072146 # Олбери / Водонга # VIC # 20091204 # 20091204 # 162014 ### 11 # 25 # 11 # 29 # 14 # 32 # 17 # 25 # 9 # 27 # 12 # 28 # 12 # 23 # Ясно. # Солнечно. # Солнечно. В основном солнечно. Мало ливней. Ветрено. # Утреннее облако. # Небольшая облачность. # Утреннее облако. # 089085 # Ararat # VIC # 20091204 # 20091204 # 161830 ### 8 # 21 # 7 # 24 # 9 # 24 # 10 # 19 # 8 # 22 # 8 # 22 # 8 # 19 # В основном ясно. # Послеобеденный душ или два . # В основном солнечно. # Душ или два. # Душ или два. # Душ или два. Ветрено. # Душ или два. # Душ или два. # 087113 # Авалон # ВИК # 20091204 # 20091204 # 161830 ### 11 # 21 # 10 # 24 # 11 # 23 # 12 # 19 # 10 # 23 # 11 # 23 # 11 # 19 # В основном ясно. # Душ или два. # Солнечный. # Душ или две развивающиеся. # Дождь. Ветрено. # Становится ветреным. # Дожди. Ветрено. Мало ливней. 085279 # Bairnsdale # VIC # 20091204 # 20091204 # 161830 ### 10 # 22 # 10 # 25 # 12 # 25 # 13 # 21 # 9 # 26 # 11 # 25 # 11 # 21 # В основном ясно. # Возможен послеобеденный душ. # Небольшая облачность. # Возможен поздний душ. # Дождь, затем душ или два. # Небольшая облачность. # Душ или два. Ветрено. # Душ или два. #

И я пытаюсь понять, как мне выбрать одну область (скажем, Арарат) и поместить имеющиеся в ней данные в массив в порядке, который имеет смысл с PHP5. У меня ограниченный опыт использования регулярных выражений, и я боюсь, что мне нужна помощь с этим.

Кроме того, форматирование этих данных стандартизировано или является чем-то частным?

Ответы [ 3 ]

2 голосов
/ 04 декабря 2009

Вы можете использовать fgetcsv () (или str_getcsv () , если у вас нет дескриптора файла).

$fp = fopen('test.txt', 'rb') or die('!fopen');

$result = array();
while(!feof($fp)) {
  $result[] = fgetcsv($fp, 0, '#');
}
var_dump($result);

edit: При необходимости / желании вы можете легко сделать его ассоциативным массивом.

$fp = fopen('test.txt', 'rb') or die('!fopen');
$keys = fgetcsv($fp, 0, '#');
$result = array();
while(!feof($fp)) {
  if ( false!=($row=fgetcsv($fp, 0, '#')) ) {
    $result[] = array_combine($keys, $row);
  }
}
var_dump($result);

(вы можете захотеть немного «растянуть» этот код для большей обработки ошибок)

Или добавьте / замените ключи позднее. Например. (используя замыкание, только php 5.3+)

$fp = fopen('test.txt', 'rb') or die('!fopen');
$result = array();
while(!feof($fp)) {
  $result[] = fgetcsv($fp, 0, '#');
}
// if there is a line break after the last record
// you might want to remove the empty entry
array_filter($result);

// get the field names and combine them with each record
$keys = array_shift($result);
$result = array_map( function($e) use($keys) { return array_combine($keys, $e); } , $result);

var_dump($result);
1 голос
/ 04 декабря 2009

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

$str = 'your input as posted in your question';

$lines   = explode("\n", $str);
$headers = explode('#', $lines[0]);
$output  = array();

for ($x = 1; $x < count($lines); $x++) {
    $fields = explode('#', $lines[$x]);
    for ($y = 0; $y < count($fields); $y++) {
        $key         = $fields[1];
        $column_name = $headers[$y];

        $output[$key][$column_name] = $fields[$y];
    }
}

// output
print_r($output);

// example of usage
echo $output['Ararat']['min_3'];
1 голос
/ 04 декабря 2009

Вам не нужно использовать регулярные выражения. fgetcsv () может с этим справиться, но вы можете легко написать свою собственную функцию разбора, которая даст вам ассоциативный массив вместо числового индексированного массива:

function parse_data($data) {
    $rows = explode("\n", $data);

    $header = array_shift($rows);
    $header_cells = explode("#", $header);

    $result = array();

    foreach($rows as $row) {
        $tmp = array();
        $cells = explode("#", $row);
        // Now $cells[0] has loc_id, $cells[1] has location etc..
        foreach($cells as $id => $cell) {
            $tmp[$header_cells[$id]] = $cell;
        }
        $result[$cells[1]] = $tmp;
    }
    return $result;
}

И используйте это так:

$data = parse_data(file_get_contents('data.txt'));

Вы можете использовать print_r(), чтобы вывести массив на экран и проверить его. Строки индексируются по местоположению, поэтому вы можете использовать $data['Ararat']; для получения данных для Арарата, а также для получения определенных полей, например, $data['Ararat']['state'];

...