根据PHP中的正则表达式对数组进行分组

时间:2015-03-13 22:19:29

标签: php arrays regex

我有一个如下所示的数组:

[0] => name {
[1] => abc
[2] => def
[3] => }
[4] => 
[5] => othername {
[6] => 123
[7] => 456
[8] => 789
[9] => }
[10] =>

正如您所看到的,每个组(在每个名称下)可以包含不同数量的行和不同的项目,但每个组以相同的正则表达式语法开头,并以结束}和之后的空白行结束。

我需要递归地为每个组(每个名称)获取一个数组。我创建了一个preg_match正则表达式,它将找到每个名称行,但我不知道如何创建一个数组,其中包含所有在下一个名称组之前的行。

所以我想获得:

array(
    array('name {', 'abc', 'def', '}'),
    array('othername {', '123', '456', '789', '}')
)

我该如何处理?提前谢谢。

3 个答案:

答案 0 :(得分:2)

凯普斯特打败了我,但我不确定他的作品/是否经过测试。这是我的解决方案

<?php
$array = array('0' => 'name {', '1' => 'abc', '2' => 'def', '3' => "}\n", '4' => "\n", 
'5' => 'othername {',
'6' => '123',
'7' => '456',
'8' => '789',
'9' => '}',
'10' => "\n");
$string = array();
$count = 0;
foreach($array as $value){
    $value = trim($value);
    $pos = strpos($value, '{');
    if ($pos !== false) {
        $count++;
    }
    if(!empty($value)) {
        $string[$count][] = $value;
    }
}
print_r($string);

答案 1 :(得分:0)

也许这段代码就是您要求的。但我自己从不使用它。如果您尝试构建代码解析器,则需要使用&#34;语法&#34;来查找parsing-trees。或语法分析。它是parsing和编译器的一部分。下面的幻灯片显示了编译器或解释器的工作方式。如果您只是为了达到某个特定目标而只是为了表示您的数据,那么您可以查看json等格式。在提出具体问题之前,您应该始终用一句话提到您的总体目标。 enter image description here(对不起德国人)

以下代码的问题是,语法变化可能会破坏代码,并且您非常容易受到影响,因为代码会将您的php变量内容更改为数组内容。

如果您正在使用代码处理文件,我建议您也要直接处理它,而不是先将其保存到数组中(这需要更多内存)。

<?php
$syntaxArray = array(
    0 => 'name {',
    1 => 'abc',
    2 => 'def',
    3 => '}',
    4 => 'othername {',
    5 => '123',
    6 => '456', 
    7 => '789',
    8 => '}'
);

$regex_open_array = '-(\w+)\s*{-';
$array_open = false;
foreach($syntaxArray as $line){
    $matches = array();
    if( preg_match($regex_open_array, $line, $matches) ){
        if($array_open){
            /*recursive array creations do not work - if that's what you need put it in the comments*/
            throw new RuntimeException('An array can not be open while the previous array is not closed');
        }
        $array_open = true;
        /*create an array variable
        * ....
        * isolate the variable name
        */
        $currentArray = $matches[1];


        /*you can either create a new variable in your php code with the array name or use a big array and use the name as key
         * $big_array[$name] = array(); 
         * using this solution every array name must be only used once. 
         * of course you can use a name twice if you first check prior to creating a new array if the key is already in use. 
         */


        /*creates a variable with the given name. Must not overwrite an other arrays name like $syntaxArray*/
        $$currentArray = array();
    }else if($line == '}'){
        /*the closing string could be wrapped with trim() or matched with a regex but I followed your example*/
        $array_open = false;
    }else{
        if(!$array_open){
            throw new RuntimeException('There is not array currently open');
        }
        $arr = &$$currentArray;
        $arr[] = $line;

    }
}

var_dump($name);
var_dump($othername);

输出:

array(2) { [0]=> string(3) "abc" [1]=> string(3) "def" } array(3) { [0]=> string(3) "123" [1]=> string(3) "456" [2]=> string(3) "789" }

答案 2 :(得分:-1)

这不是真正的正则表达式。你想要做的是遍历数组,并检查每个项目。您可以在那里搜索一下&#39; {&#39;或者&#39;}&#39;。当您看到一个左括号时,您可以在&#34;浓缩&#34;中设置密钥。要索引的数组,然后检查结束括号的后续项目。当您看到结束括号时,您需要在&#34;浓缩&#34;中更改您正在编入索引的键。数组或其他什么,重新开始。当值不是括号时,请附加它。它会看起来像这样(抱歉PHP的错误):

$big_array = array();
$temp_key = NULL;
foreach (array as $key => $value) {
    if (strpo($value, '{')) {
        $big_array[$key] = array();
        $temp_key = $key;
    } else if (strpos($value, '}')) {
         $temp_key = NULL;
    } else {
         $big_array[$temp_key].append($value); // or whatever
    }

}

这假设你有一个匹配的开/关括号结构,当然你想加入大量的错误检查。