Search code examples
phparraysforeachpreg-match-alltext-parsing

Parse formatted strings containing 3 delimiters to create multiple flat arrays


I have strings in following format:

$strings[1] = cat:others;id:4,9,13
$strings[2] = id:4,9,13;cat:electric-products
$strings[3] = id:4,9,13;cat:foods;
$strings[4] = cat:drinks,foods;

where cat means category and id is identity number of a product.

I want to split these strings and convert into arrays $cats = array('others'); and $ids = array('4','9','13');

I know that it can be done by foreach and explode function through multiple steps. I think I am somewhere near, but the following code does not work.

Also, I wonder if it can be done by preg_match or preg_split in fewer steps. Or any other simpler method.

foreach ($strings as $key=>$string) {
   $temps = explode(';', $string);
   foreach($temps as $temp) {
      $tempnest = explode(':', $temp);
      $array[$tempnest[0]] .= explode(',', $tempnest[1]);
   }
}

My desired result should be:

$cats = ['others', 'electric-products', 'foods', 'drinks';

and

$ids = ['4','9','13'];

Solution

  • One option could be doing a string compare for the first item after explode for cat and id to set the values to the right array.

    $strings = ["cat:others;id:4,9,13", "id:4,9,13;cat:electric-products", "id:4,9,13;cat:foods", "cat:drinks,foods"];
    
    foreach ($strings as $key=>$string) {
        $temps = explode(';', $string);
        $cats = [];
        $ids = [];
        foreach ($temps as $temp) {
            $tempnest = explode(':', $temp);
    
            if ($tempnest[0] === "cat") {
                $cats = explode(',', $tempnest[1]);
            }
            if ($tempnest[0] === "id") {
                $ids = explode(',', $tempnest[1]);
            }
        }
        print_r($cats);
        print_r($ids);
    }
    

    Php demo

    Output for the first item would for example look like

    Array
    (
        [0] => others
    )
    Array
    (
        [0] => 4
        [1] => 9
        [2] => 13
    )
    

    If you want to aggregate all the values in 2 arrays, you can array_merge the results, and at the end get the unique values using array_unique.

    $strings = ["cat:others;id:4,9,13", "id:4,9,13;cat:electric-products", "id:4,9,13;cat:foods", "cat:drinks,foods"];
    $cats = [];
    $ids = [];
    foreach ($strings as $key=>$string) {
        $temps = explode(';', $string);
    
        foreach ($temps as $temp) {
            $tempnest = explode(':', $temp);
    
            if ($tempnest[0] === "cat") {
                $cats = array_merge(explode(',', $tempnest[1]), $cats);
            }
            if ($tempnest[0] === "id") {
                $ids = array_merge(explode(',', $tempnest[1]), $ids);
            }
        }
    
    }
    print_r(array_unique($cats));
    print_r(array_unique($ids));
    

    Output

    Array
    (
        [0] => drinks
        [1] => foods
        [3] => electric-products
        [4] => others
    )
    Array
    (
        [0] => 4
        [1] => 9
        [2] => 13
    )
    

    Php demo