在PHP中基于专家级字符串创建数组

时间:2018-11-04 11:57:05

标签: php arrays regex parsing preg-match-all

我有一个基于此create an array based on a specific string in php答案的字符串。我想扩展一下:

$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]';

并将其划分如下:

$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']
    ),
);

当前代码:

if(preg_match_all('~\[(\w+):\s*([^][]*)]~', $content, $matches)){
    array_shift($matches);
    array_combine($matches[0], $matches[1]);
}

这个解决方案是真实的,值得吗?

在此先感谢您的帮助,我对我的英语表示歉意。

1 个答案:

答案 0 :(得分:2)

\G“继续”元字符就是这种模式的英雄。 https://www.regular-expressions.info/continue.html这样可以使模式无限扩展,以防将来您要添加更多带括号的键值对。

找到id号之后,该模式将寻找一个非常可预测的方括号结构,并且直到字符串中断延续模式后才停止匹配。

一旦生成$matches数组,您只需要隔离哪些匹配项就是id数字。由于id组匹配项中没有[2]元素,因此请检查isset($item[2])-如果不存在,则将id存储在{{1 }},否则存储键值对。

代码:(Demo)(Regex101 Demo

$item[1]

输出:

$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);