Search code examples
phparraysregexstringstring-parsing

Parse a formatted, single-line string into an array of associative arrays with predefined column names


I've got a problem that seems simple on the face of it but has defeated my meager regex skills. I have a string that I need to convert to an array and then process the values accordingly, which is simple enough, but the format of the string cannot be changed (it is generated elsewhere) and the logic of it has me baffled.

The string is:

[6] [2] [3] 12.00; [5] [4]

It's basically a set of ids and decimal values (in this case id 3 == 12.00). The quantity of ids could change at any moment and decimal values could be in any or all of the ids.

In an ideal world I would have the following array:

Array (
   [0] => Array (
             [id]  => 6
             [num] => 
          )
   [1] => Array (
             [id]  => 2
             [num] => 
          ) 
   [2] => Array (
             [id]  => 3
             [num] => 12.00 
          )
   Etc...

Do any of you regex wizards know how this can be accomplished with less swearing than I've been able to achieve?

I have thus far been able to extract the id's using:

preg_match_all('@\[(.*?)\]@s', $string, $array);

and the decimals using:

preg_match_all('/([0-9]+[,\.]{1}[0-9]{2})/', $string, $array);

but lose the correlation between id's and values.


Solution

  • Example:

    <?php
    
    $string = '[6] [2] [3] 12.00; [5] [4]';
    
    preg_match_all('/\[(?P<id>\d+)\](?: (?P<num>[\d\.]+);)?/', $string, $matches, PREG_SET_ORDER);
    
    var_dump($matches);
    

    Output:

    array(5) {
      [0]=>
      array(3) {
        [0]=>
        string(3) "[6]"
        ["id"]=>
        string(1) "6"
        [1]=>
        string(1) "6"
      }
      [1]=>
      array(3) {
        [0]=>
        string(3) "[2]"
        ["id"]=>
        string(1) "2"
        [1]=>
        string(1) "2"
      }
      [2]=>
      array(5) {
        [0]=>
        string(10) "[3] 12.00;"
        ["id"]=>
        string(1) "3"
        [1]=>
        string(1) "3"
        ["num"]=>
        string(5) "12.00"
        [2]=>
        string(5) "12.00"
      }
      [3]=>
      array(3) {
        [0]=>
        string(3) "[5]"
        ["id"]=>
        string(1) "5"
        [1]=>
        string(1) "5"
      }
      [4]=>
      array(3) {
        [0]=>
        string(3) "[4]"
        ["id"]=>
        string(1) "4"
        [1]=>
        string(1) "4"
      }
    }