Search code examples
phparraysmultidimensional-arrayassociative-arraytext-parsing

Parse a multi-line block of delimited text to create an array of associative rows


I am getting a multi-line block of text from the single column of a database query result set like this:

$data = <<<DATA
DATE      = FEE = PAYMENT
2021-03-09 = 119.25 = 119.25 = 2021-04-13

2021-03-15 = 119.25 = 119.25 = 2021-04-13
DATA;

I need to parse this text, ignore the header line and any blank lines, extract the first and second values in each line (a date and a float value), then populate an array of associative arrays.

Desired result:

[
    {"Date": "2021-01-23", "fee": 0.00, "title": "example" },
    {"Date": "2021-01-31", "fee": 0.00, "title": "example" },    
]

My current code:

$data = implode("=", $data);
$data = str_replace("\n", "=", $data);
$data = str_replace("       ", "", $data);
$data = explode("=", $data);

But my result looks like this:

Array
(
    [0] => DATE
    [1] =>  FEE 
    [2] =>  PAYMENT
    [3] => 2021-01-23
    [4] =>  119.25 
    [5] =>  119.25 
    [6] =>  2021-01-31
    [7] => 2021-01-31 
    [8] =>  119.25 
    [9] =>  119.25 
    [10] =>  2021-04-13
)

I also tried iterating and saving every n row:

$result = array();
$data = array_values($data);
$count = count($data);
for($i = 0; $i < $count; $i += 4) {
    $result =  ["Date".$i => $data[$i]];
}
for($i = 0; $i < $count; $i += 2) {
    $result["fee"] =  $data[$i];
}

Solution

  • You need to first split by newline, drop the first row and then split again by equals sign. Trim to remove the spaces and add as an array. At the end convert the array to a JSON string.

    $result = 'DATE      = FEE = PAYMENT
    2021-03-09 = 119.25 = 119.25 = 2021-04-13
    
    2021-03-15 = 119.25 = 119.25 = 2021-04-13';
    
    $rows = explode("\n", $result);
    array_shift($rows);
    
    $results = [];
    foreach ($rows as $row) {
        $row = trim($row);
        if (empty($row)) continue;
        [$date, $fee] = array_map('trim', explode('=', $row));
        $results[] = [
            'date'  => $date,
            'fee'   => floatval($fee),
            'title' => 'example',
        ];
    }
    
    echo json_encode($results, JSON_PRETTY_PRINT);
    

    Output

    [
        {
            "date": "2021-03-09",
            "fee": 119.25,
            "title": "example"
        },
        {
            "date": "2021-03-15",
            "fee": 119.25,
            "title": "example"
        }
    ]