PHP-对嵌套数组执行解析规则

时间:2019-05-16 08:17:37

标签: php arrays laravel transformation

所以我有一个嵌套的数组,它模仿表的布局(列和行):

{
    "1": [
        {
            "row": "My name is Trevor\n"
        },
        {
            "row": "Can you see me?\n"
        },
        {
            "row": "\f"
        }
    ],
    "2": [
        {
            "row": Hey there! Some other text.\n"
        },
        {
            "row": "What is up?\n"
        },
        {
            "row": "\f"
        }
    ],
    "3": [
        {
            "row": "Some text on the third column. First row."
        },
        {
            "row": "\f"
        }
    ]
}

因此,“ 1”,“ 2”,“ 3”是列,然后在每一列下可以有任意数量的行。

现在我正在尝试做,因此我的用户可以在其中一个上执行各种解析规则:

  1. 所有列和所有行。
  2. 特定列和所有行。

每当解析了列/行时,都应将其返回到“原始数组”。

为此,我创建了一个类,该类将应用指定的不同解析规则。获取解析规则可以正常工作。我目前停留在实际的文本转换/解析方面。

考虑一下,我有一个名为“ regexTextReplace”的解析规则,如下所示:

class regexTextReplace
{
    private $pattern;
    private $replacement;

    public function __construct(array $arguments)
    {
        $this->pattern = $arguments['pattern'];
        $this->replacement = $arguments['replacement'];
    }

    public function apply(array $table, $column = false): array
    {
        $table = $column ? $table[$column] : $table;

        return array_map('self::regex_replace', $table);
    }

    public function regex_replace(array $table)
    {
        return preg_replace($this->pattern, $this->replacement, $table);
    }
}

这是我的使用方式:

$options = [
    'pattern' => '/Trevor/i',
    'replacement' => 'Oliver',
];
$engine = new regexTextReplace($options);
$columns = $engine->apply($document->content, 1); //"1" is the specific column.

$columns返回:

[
  {
    "row": "My name is Oliver\n"
  },
  {
    "row": "Can you see my?\n"
  },
  {
    "row": "\f"
  }
]

这里有两个问题:

  1. 它成功应用了解析规则(Trever被Oliver取代了)。但是它只返回第一列,但我希望将整个原始数组进行转换。
  2. 如果我从1方法中删除了apply(),则会收到以下错误消息:
Array to string conversion

在下面的行上:

return preg_replace($this->pattern, $this->replacement, $table);

任何人都可以朝着正确的方向引导我,以便我可以在任何列或所有列上执行解析规则,然后将转换后的数据返回到我的原始数组?

3 个答案:

答案 0 :(得分:6)

我将重写apply函数以遍历整个表,如果未设置column参数或它与当前表的列匹配,则处理每一列:

public function apply(array $table, $column = false): array
{
    $out = array();
    foreach ($table as $col => $rows) {
        if ($column === false || $col == $column) {
            $out[$col] = array_map('self::regex_replace', $rows);
        }
        else {
            $out[$col] = $rows;
        }
    }
    return $out;
}

Demo on 3v4l.org

答案 1 :(得分:3)

您可以将<cdk-virtual-scroll-viewport class="items" itemSize="50" class="items"> <div *cdkVirtualFor="let merch of getBasket() | keyvalue" > <!-- 1. row --> <mat-grid-list cols="11" rowHeight="1:2"> .... <mat-grid-tile rowspan="1" colspan="1"> <button mat-icon-button (click)="removeFromBasket(merch.key)"> <i class="fas fa-minus"></i> </button> </mat-grid-tile> .... </mat-grid-list> <mat-divider></mat-divider> </div> </cdk-virtual-scroll-viewport> 方法重写为此:

apply

您可以传递单列或列数组,也可以不传递任何内容(public function apply(array $table, $columns = false): array { $columns = $columns === false ? array_keys($table) : (array)$columns; return array_map(function ($column) use ($table, $columns) { return in_array($column, $columns) ? array_map('self::regex_replace', $table[$column]) : $table[$column]; }, array_keys($table)); } )来指定要调整的列。

演示:https://3v4l.org/Kn4FY

答案 2 :(得分:2)

只需循环并在所有子数组上执行正则表达式:

$content = json_decode($json, true);

$options = [
    'pattern' => '/Trevor/i',
    'replacement' => 'Oliver',
];
$engine = new regexTextReplace($options);
foreach($content as $key => $v){
    $columns[$key] = $engine->apply($content, $key);
}
var_dump($columns);

工作演示:
https://3v4l.org/Pk2rC

在“ PHP”端而不是在类中循环的好处是,您仍然可以仅将正则表达式应用于一个或两个子数组。
如果在类中循环,则需要传递更多参数以限制循环或执行某种类型的数组切片。