PHP - выполнение правил синтаксического анализа для вложенного массива - PullRequest
12 голосов
/ 16 мая 2019

Итак, у меня есть вложенный массив, который имитирует макет таблицы (столбцы и строки):

{
    "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", которое выглядит так:используя его:

$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. Он успешно применяет правило разбора (Тревер заменен Оливером).Но он возвращает только первый столбец, но я хочу преобразовать весь исходный массив.
  2. Если я удаляю 1 из метода apply(), я получаю ошибку ниже:
Array to string conversion

в строке ниже:

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

Может ли кто-нибудь направить меня в правильном направлении, чтобы я мог выполнить свое правило синтаксического анализа для любого столбца или для всех столбцов и вернуть преобразованные данные обратно вмой оригинальный массив?

Ответы [ 3 ]

6 голосов
/ 16 мая 2019

Я бы переписал функцию 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;
}

Демонстрация на 3v4l.org

3 голосов
/ 16 мая 2019

Вы можете переписать свой метод 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));
}

Вы можете передать либо один столбец, либо массив столбцов, либо ничего (false), чтобы указать нужные столбцыотрегулировано.

Демо: https://3v4l.org/Kn4FY

2 голосов
/ 16 мая 2019

Просто зациклите его и выполните регулярное выражение для всех подмассивов:

$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", а не в классе, состоит в том, что вы все равно можете применять регулярное выражение только к одному или двум подмассивам.
Если вы зациклились в классе, вам нужно передать больше аргументов, чтобы ограничить зацикливание или выполнить какой-либо тип нарезки массива.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...