So I have a nested array, that mimics a table layout (columns and rows):
{
    "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"
        }
    ]
}
So "1", "2", "3" are the columns and then under each column, there can be any number of rows.
Now I am trying to do, so my users can perform various parsing rules on either:
Whenever a column / row has been parsed, it should be returned to the "original array".
For this, I have created a class that will apply the different parsing rules I have in specified. Getting the parsing rule works fine. I am currently stuck in the actual text transformation/parsing aspect.
Consider I have a parsing rule called "regexTextReplace", that looks like this:
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);
    }
}
This is how I'm using it:
$options = [
    'pattern' => '/Trevor/i',
    'replacement' => 'Oliver',
];
$engine = new regexTextReplace($options);
$columns = $engine->apply($document->content, 1); //"1" is the specific column.
$columns returns:
[
  {
    "row": "My name is Oliver\n"
  },
  {
    "row": "Can you see my?\n"
  },
  {
    "row": "\f"
  }
]
Two problems here:
1 from the apply() method, I get below error:Array to string conversion
on below line:
return preg_replace($this->pattern, $this->replacement, $table);
Can anyone guide me in the right direction, so I can perform my parsing rule on any column or on all columns, and return the transformed data back to my original array?
I would rewrite the apply function to loop over the entire table, processing each column if the column argument is not set, or if it matches the current table 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
You could rewrite your apply method to this:
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));
}
You can pass either a single column, or an array of columns, or nothing (false) to specify the columns you want adjusted.
Demo: https://3v4l.org/Kn4FY
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With