phpstrtr

How to parse a string into multiple variables based on an input mask indicating the order?


Assuming you start with this:

$mask = "%name% (%user_count%) - %acyr% - %audience%";
$data = [
    '%name%'       => $group['name'],
    '%user_count%' => $group['user_count'],
    '%acyr%'       => $group['acyr'],
    '%audience%'   => $group['audience'],
];
$result = strtr($mask, $data);

What is the best way of reversing this such that you transform $result into the following defined and populated variables? (Also bear in mind that the order of $mask could change.)

$name       = '?';
$user_count = '?';
$acyr       = '?';
$audience   = '?';

I have tried using preg_split() / list() but I want $mask to govern the order of the variables without having to convert it into a complicated regex. Basically I need a simple method of parsing/splitting a string into multiple variables based on a mask containing placeholders.


Solution

  • The mask can be changed by altering the order of the placeholders or adding new punctuation yet the logic is flexible enough to generate the variables.

    PHP code demo

    <?php
        $mask = "%name% (%user_count%) - %acyr% - %audience%";
        $data = [
            '%name%'       => 'Year 1',
            '%user_count%' => 999,
            '%acyr%'       => 2017,
            '%audience%'   => 'Staff and Students',
        ];
        $result = strtr($mask, $data);
    
        // Extract unique punctuation used in mask and form pattern for split
        $pattern = '/[' . preg_replace('/[\w\s%]/', '', count_chars($mask, 3)) . ']/';
    
        // Split, trim, remove blanks and reset array keys
        $variables = array_values(array_filter(array_map('trim', preg_split($pattern, $mask, -1, PREG_SPLIT_NO_EMPTY)), 'strlen'));
        $data      = array_values(array_filter(array_map('trim', preg_split($pattern, $result, -1, PREG_SPLIT_NO_EMPTY)), 'strlen'));
    
        foreach ($variables as $key => $variable_name) {
            $variable_name = str_replace('%', '', $variable_name);
            // Dynamically create variable
            ${$variable_name} = $data[$key];
        }
    
        var_dump("\$name: $name");             // Year 1
        var_dump("\$user_count: $user_count"); // 999
        var_dump("\$acyr: $acyr");             // 2017
        var_dump("\$audience: $audience");     // Staff and Students