I have a string divided based on the answers from this create an array based on a specific string in php. I would like to extend it a bit:
$content = '
[2130701433] [NAME: aaa] [VALUE: aaa] [EXPIRE: 1 second] [CREATED: Y:m:d H:i:s]
[2130701433] [NAME: bbb] [VALUE: bbb] [EXPIRE: 2 minute] [CREATED: Y:m:d H:i:s]
[2130701433] [NAME: ccc] [VALUE: ccc] [EXPIRE: 3 hours] [CREATED: Y:m:d H:i:s]
[2130701434] [NAME: aaa] [VALUE: aaa] [EXPIRE: 1 second] [CREATED: Y:m:d H:i:s]
[2130701434] [NAME: bbb] [VALUE: bbb] [EXPIRE: 2 minute] [CREATED: Y:m:d H:i:s]
[2130701434] [NAME: ccc] [VALUE: ccc] [EXPIRE: 3 hours] [CREATED: Y:m:d H:i:s]
[2130701435] [NAME: aaa] [VALUE: aaa] [EXPIRE: 1 second] [CREATED: Y:m:d H:i:s]
[2130701435] [NAME: bbb] [VALUE: bbb] [EXPIRE: 2 minute] [CREATED: Y:m:d H:i:s]
[2130701435] [NAME: ccc] [VALUE: ccc] [EXPIRE: 3 hours] [CREATED: Y:m:d H:i:s]';
And divide it as follows:
$content = array(
'2130701433' => array(
'NAME' => ['aaa', 'bbb', 'ccc'],
'VALUE' => ['aaa', 'bbb', 'ccc'],
'EXPIRE' => ['1 second', '2 minute', '3 hours'],
'CREATED' => ['Y:m:d H:i:s', 'Y:m:d H:i:s', 'Y:m:d H:i:s']
),
'2130701434' => array(
'NAME' => ['aaa', 'bbb', 'ccc'],
'VALUE' => ['aaa', 'bbb', 'ccc'],
'EXPIRE' => ['1 second', '2 minute', '3 hours'],
'CREATED' => ['Y:m:d H:i:s', 'Y:m:d H:i:s', 'Y:m:d H:i:s']
),
'2130701435' => array(
'NAME' => ['aaa', 'bbb', 'ccc'],
'VALUE' => ['aaa', 'bbb', 'ccc'],
'EXPIRE' => ['1 second', '2 minute', '3 hours'],
'CREATED' => ['Y:m:d H:i:s', 'Y:m:d H:i:s', 'Y:m:d H:i:s']
),
);
Current code:
if(preg_match_all('~\[(\w+):\s*([^][]*)]~', $content, $matches)){
array_shift($matches);
array_combine($matches[0], $matches[1]);
}
Is this solution real and is it worth it?
Thank you in advance for your help and I apologize for my English.
The \G
"continue" metacharacter is the hero of this pattern. https://www.regular-expressions.info/continue.html This makes the pattern infinitely extensible in case you want to add more bracketed key-value pairs in the future.
After the id
number is found, the pattern seeks a very predictable bracketed structure and doesn't stop matching until the string breaks the continuation pattern.
Once the $matches
array is generated, you only need to isolate which matches are the id
numbers. Because the id
set of matches doesn't have a [2]
element, check for isset($item[2])
-- if it doesn't exist, store the id
located at $item[1]
, otherwise store the key-value pair.
Code: (Demo) (Regex101 Demo)
$content = '
[2130701433] [NAME: aaa] [VALUE: aaa] [EXPIRE: 1 second] [CREATED: Y:m:d H:i:s]
[2130701433] [NAME: bbb] [VALUE: bbb] [EXPIRE: 2 minute] [CREATED: Y:m:d H:i:s]
[2130701433] [NAME: ccc] [VALUE: ccc] [EXPIRE: 3 hours] [CREATED: Y:m:d H:i:s]
[2130701434] [NAME: aaa] [VALUE: aaa] [EXPIRE: 1 second] [CREATED: Y:m:d H:i:s]
[2130701434] [NAME: bbb] [VALUE: bbb] [EXPIRE: 2 minute] [CREATED: Y:m:d H:i:s]
[2130701434] [NAME: ccc] [VALUE: ccc] [EXPIRE: 3 hours] [CREATED: Y:m:d H:i:s]
[2130701435] [NAME: aaa] [VALUE: aaa] [EXPIRE: 1 second] [CREATED: Y:m:d H:i:s]
[2130701435] [NAME: bbb] [VALUE: bbb] [EXPIRE: 2 minute] [CREATED: Y:m:d H:i:s]
[2130701435] [NAME: ccc] [VALUE: ccc] [EXPIRE: 3 hours] [CREATED: Y:m:d H:i:s]';
if(preg_match_all('~\G\s*\[(\d+)]|\s*\[([A-Z]+):\s*(.*?)]~', $content, $matches, PREG_SET_ORDER)){
//var_export($matches);
foreach ($matches as $item) {
if (!isset($item[2])) {
$id = $item[1];
} else {
$result[$id][$item[2]][] = $item[3];
}
}
}
var_export($result);
Output:
array (
2130701433 =>
array (
'NAME' =>
array (
0 => 'aaa',
1 => 'bbb',
2 => 'ccc',
),
'VALUE' =>
array (
0 => 'aaa',
1 => 'bbb',
2 => 'ccc',
),
'EXPIRE' =>
array (
0 => '1 second',
1 => '2 minute',
2 => '3 hours',
),
'CREATED' =>
array (
0 => 'Y:m:d H:i:s',
1 => 'Y:m:d H:i:s',
2 => 'Y:m:d H:i:s',
),
),
2130701434 =>
array (
'NAME' =>
array (
0 => 'aaa',
1 => 'bbb',
2 => 'ccc',
),
'VALUE' =>
array (
0 => 'aaa',
1 => 'bbb',
2 => 'ccc',
),
'EXPIRE' =>
array (
0 => '1 second',
1 => '2 minute',
2 => '3 hours',
),
'CREATED' =>
array (
0 => 'Y:m:d H:i:s',
1 => 'Y:m:d H:i:s',
2 => 'Y:m:d H:i:s',
),
),
2130701435 =>
array (
'NAME' =>
array (
0 => 'aaa',
1 => 'bbb',
2 => 'ccc',
),
'VALUE' =>
array (
0 => 'aaa',
1 => 'bbb',
2 => 'ccc',
),
'EXPIRE' =>
array (
0 => '1 second',
1 => '2 minute',
2 => '3 hours',
),
'CREATED' =>
array (
0 => 'Y:m:d H:i:s',
1 => 'Y:m:d H:i:s',
2 => 'Y:m:d H:i:s',
),
),
)