反转括号分组文本的顺序并反转括号组的顺序

问题描述 投票:0回答:2

我有一个带图案的字符串,像这样:

(X,1,1,3),(X,1,1,3),(X,@2,@2,@2,@2,@2,(Y,1))

我需要从这个大数组中提取,倒序排列,并生成新的字符串:

(X,(Y,1),@2,@2,@2,@2,@2),(X,3,1,1),(X,3,1,1)

和预期的数组:

Array (
    [0] => Array(
        [parent] => (X,1,1,3)
        [childs] => Array(
            [0] => X
            [1] => 1
            [2] => 1
            [3] => 3
        )
    [1] => Array(
        [parent] => (X,1,1,3)
        [childs] => Array(
            [0] => X
            [1] => 1
            [2] => 1
            [3] => 3
        )
    [2] => Array(
        [parent] => (X,@2,@2,@2,@2,@2,(Y,1))
        [childs] => Array(
            [0] => X
            [1] => @2
            [2] => @2
            [3] => @2
            [4] => @2
            [5] => @2
            [6] => (Y,1)
        )
)

目前,我只有使用此代码的父母的第一级:

   foreach($datasetxml->Solution->Pattern as $el){

        if(substr( $el["Str"], 0, 1 ) === "L"){

            preg_match_all("/\((((?>[^()]+)|(?R))*)\)/", $el["Str"], $text);

            $text = $text[0];

            $text = array_reverse($text);
            
            foreach($text as $t){            
                //$t = str_replace(")", "", $t);
                $new_texts[] = $t;            
            }        
            $new_text = implode(",", $new_texts);        
            $el["Str"] = $new_text;
        }    

    }
php regex string reverse parentheses
2个回答
1
投票

我可以通过将其转换为 JSON 来反转您的模式,然后对其进行解码和操作。代码如下所示:

<?php

function reverseRecursive($array, $recursing = false) {
    foreach ($array as $key => $value) {
        if (is_array($value)) {
            $array[$key] = '(' . reverseRecursive($value, true) . ')';
        }    
    }
    $first = $recursing ? array_shift($array) . ',' : '';
    return $first . implode(',', array_reverse($array));
}

$data    = '(X,1,1,3),(X,1,1,3),(X,@2,@2,@2,@2,@2,(Y,1))';
$json    = preg_replace(['/[^(),]+/', '/\(/', '/\)/'], 
                        ['"$0"', '[', ']'], "($data)");
$inverse = reverseRecursive(json_decode($json));

echo $inverse;

这会导致:

(X,(Y,1),@2,@2,@2,@2,@2),(X,3,1,1),(X,3,1,1)

可以在此处找到演示:https://3v4l.org/kISpv

preg_replace() 用于将模式转换为 JSON。然后对其进行解码,以便可以在 PHP 中进行处理。

reverseRecursive()
对数组进行基本的递归反转,将除外部数组之外的第一项保留在原位,并再次将其内爆为字符串。

我不明白你的“预期数组”与此有什么关系,所以我不知道如何回答你问题的这一部分。


1
投票

我不知道这对各种输入的支持效果如何,但它被设计为在其分裂、反转、内爆行为中递归,同时保留第一个条目在每个括号组中的位置。

第一个正则表达式隔离父级括号段并删除外括号。第二个正则表达式将下一级的子级隔离。第一个孩子被分开,因为它不会被重新定位。任何剩余的子级都可能被递归处理,然后所有子级都被反转并附加到第一个子级。最后,所有父级段(及其反转的子级)的顺序都颠倒了,并用括号重新括起来。

我相当有信心,这项任务太小众,无法帮助其他开发人员。

代码:(演示

function rSplitReverse($string) {
    preg_match_all("/\(((?:(?>[^()]+)|(?R))*)\)/", $string, $matches);
    foreach ($matches[1] as &$m) {
        if (preg_match_all("/(\((?:(?>[^()]+)|(?R))*\))|[^(),]+/", $m, $items, PREG_SET_ORDER)) {
            $first = array_shift($items)[0];
            foreach ($items as &$item) {
                $item = isset($item[1]) ? rSplitReverse($item[0]) : $item[0];
            }
            $m = "$first," . implode(',', array_reverse($items));
        }
    }
    return '(' . implode('),(', array_reverse($matches[1])) . ')';
}

echo rSplitReverse('(X,1,1,3),(X,1,1,3),(X,@2,@2,@2,@2,@2,(Y,1))');
// (X,(Y,1),@2,@2,@2,@2,@2),(X,3,1,1),(X,3,1,1)
© www.soinside.com 2019 - 2024. All rights reserved.