我有一个带图案的字符串,像这样:
(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;
}
}
我可以通过将其转换为 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()
对数组进行基本的递归反转,将除外部数组之外的第一项保留在原位,并再次将其内爆为字符串。
我不明白你的“预期数组”与此有什么关系,所以我不知道如何回答你问题的这一部分。
我不知道这对各种输入的支持效果如何,但它被设计为在其分裂、反转、内爆行为中递归,同时保留第一个条目在每个括号组中的位置。
第一个正则表达式隔离父级括号段并删除外括号。第二个正则表达式将下一级的子级隔离。第一个孩子被分开,因为它不会被重新定位。任何剩余的子级都可能被递归处理,然后所有子级都被反转并附加到第一个子级。最后,所有父级段(及其反转的子级)的顺序都颠倒了,并用括号重新括起来。
我相当有信心,这项任务太小众,无法帮助其他开发人员。
代码:(演示)
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)