Reputation: 133
I need to parse a text file into php array. Here is my text file :
file: slide1.jpg | title: Title here | description: Aenean eleifend ultrices leo at venenatis. Suspendisse luctus | crop: top
file: slide2.jpg | description: Phasellus ac tortor ut dolor blandit tincidunt | title: Nullam cursus | crop: bottom
file: slide3.jpg | title: Hendrerit lacinia nisl | description: Tortor ut dolor blandit tincidunt | crop: bottom
file: slide4.jpg | title: Morbi hendrerit lacinia nisl | description: Maecenas venenatis lectus vitae | crop: left
I want to parse it into such structured array :
array(4) {
"slide1.jpg" => array (
"title" => "Title here",
"description" => "Aenean eleifend ultrices leo at venenatis. Suspendisse luctus",
"crop" => "top"
),
"slide2.jpg" => array (
"title" => "Nullam cursus",
"description" => "Phasellus ac tortor ut dolor blandit tincidunt",
"crop" => "top"
),
"slide3.jpg" => array (
"title" => "Hendrerit lacinia nisl",
"description" => "Tortor ut dolor blandit tincidunt",
"crop" => "top"
),
"slide4.jpg" => array (
"title" => "Morbi hendrerit lacinia nisl",
"description" => "Maecenas venenatis lectus vitae",
"crop" => "top"
)
}
I tried with a many repetitive foreach statements but it was not so efficient and the code got very lengthy. Does anybody know a way to achieve it simpler.
Upvotes: 2
Views: 888
Reputation: 21727
First of all: Be Careful!
This is potentially hairy thing with many possible exceptions. The solution I provide does:
|
, which will trip up this thing. On the other hand, a value may safely contain colons."file"
is always present.Take these notes into consideration before blindly copy/pasting! ;)
In addition, my solution contains the file-name in each element, which is redundant. But removing it would have made the solution messier without much gained value.
Here's a solution:
<?php
/**
* Parse a line of the file. Returns an associative array, using the part
* before the colon as key, the following part as value.
*
* @param $line A line of text.
*/
function parse_line($line) {
// split on each '|' character.
$fields = explode('|', $line);
$data = array();
foreach($fields as $field) {
// unpack key/value from each 'key: value' text. This will only split on
// the first ":", so the value may contain colons.
list($key, $value) = explode(':', $field, 2);
// remove surrounding white-space.
$key = trim($key);
$value = trim($value);
$data[$key] = $value;
}
return $data;
}
/**
* Parses a file in the specified format.
*
* Returns an associative array, where the key is a filename, and the value is
* an associative array of metadata.
*
* @param $fname The filename
*/
function parse_file($fname) {
$handle = fopen($fname, "r");
$lines = array();
if ($handle) {
while (($line = fgets($handle)) !== false) {
$data = parse_line($line);
$lines[$data["file"]] = $data;
}
} else {
// error opening the file.
}
return $lines;
}
var_dump(parse_file("testdata.txt"));
Upvotes: 4
Reputation: 93348
The following should do the trick.
$rows = array();
foreach (preg_split('#\n#', file_get_contents('blah.txt')) as $line) {
if (preg_match_all('#([^"|]+)\s*:\s*([^|]+)#', $line, $parts)) {
$properties = array_map('trim', $parts[1]);
$values = array_map('trim', $parts[2]);
assert(count($properties) == count($values));
$row = array();
foreach ($properties as $index => $propertyName) {
$row[$propertyName] = $values[$index];
}
$rows[] = $row;
}
}
var_dump($rows);
Upvotes: 1
Reputation: 776
Try:
$new_array = array();
while (($data = fgetcsv($csvfile, 1000, ";")) !== FALSE) {
$new_array[$data[0]] = array('title' => $data[1], 'description' => $data[2], 'crop' => $data[3]);
}
var_dump($new_array);
Upvotes: -1