Шаблон разработки для парсинга данных двоичного файла и хранения в базе данных

В регулярном выражении вы можете «захватить» части согласованной строки с помощью (brackets); в этом случае вы захватываете (^|_) и ([a-z]) части матча. Они нумеруются начиная с 1, поэтому у вас есть обратные ссылки 1 и 2. Матч 0 - это вся строка с согласованием.

Модификатор /e принимает заменяющую строку и заменяет обратную косую черту с последующим номером ( например, \1) с соответствующей обратной ссылкой, но поскольку вы находитесь внутри строки, вам нужно избежать обратной косой черты, чтобы вы получили '\\1'. Затем он (эффективно) запускает eval, чтобы запустить результирующую строку, как если бы это был PHP-код (поэтому он устарел, потому что его легко использовать eval небезопасным способом).

Функция preg_replace_callback вместо этого выполняет функцию обратного вызова и передает ей массив, содержащий совпадающие обратные ссылки. Итак, где бы вы написали '\\1', вместо этого вы получите доступ к элементу 1 этого параметра - например. если у вас есть анонимная функция формы function($matches) { ... }, первая обратная ссылка - $matches[1] внутри этой функции.

Итак, аргумент /e в

'do_stuff(\\1) . "and" . do_stuff(\\2)'

может стать обратным вызовом

function($m) { return do_stuff($m[1]) . "and" . do_stuff($m[2]); }

. Или в вашем случае

'strtoupper("\\2")'

может стать

function($m) { return strtoupper($m[2]); }

Обратите внимание, что $m и $matches не являются волшебными именами, это просто имя параметра, которое я дал при объявлении моих функций обратного вызова. Кроме того, вам не нужно передавать анонимную функцию, это может быть имя функции в виде строки или что-то вроде формы array($object, $method), как с любым обратным вызовом в PHP , например

function stuffy_callback($things) {
    return do_stuff($things[1]) . "and" . do_stuff($things[2]);
}
$foo = preg_replace_callback('/([a-z]+) and ([a-z]+)/', 'stuffy_callback', 'fish and chips');

Как и в любой функции, вы не можете получить доступ к переменным вне вашего обратного вызова (из окружения) по умолчанию. При использовании анонимной функции вы можете использовать ключевое слово use для импорта переменных, которые вам нужны для доступа, , как описано в руководстве по PHP . например если старый аргумент был

'do_stuff(\\1, $foo)'

, тогда новый обратный вызов может выглядеть как

function($m) use ($foo) { return do_stuff($m[1], $foo); }

Gotchas

  • Использование preg_replace_callback - вместо модификатора /e в регулярном выражении, поэтому вам нужно удалить этот флаг из вашего аргумента «pattern». Таким образом, шаблон, подобный /blah(.*)blah/mei, станет /blah(.*)blah/mi.
  • Модификатор /e использовал внутри аргумента addslashes() вариант, поэтому некоторые замены использовали stripslashes() для его удаления; в большинстве случаев вы, вероятно, хотите удалить вызов stripslashes из вашего нового обратного вызова.

6
задан Keith Pinson 10 February 2013 в 06:43
поделиться

4 ответа

  1. Просто запишите, что Ваш синтаксический анализатор файла, с помощью любых методов приходит на ум
  2. Запишите много модульных тестов на него, чтобы удостовериться, что все Ваши пограничные случаи покрыты

После того как Вы сделали это, у Вас на самом деле будет разумная идея проблемы/решения.

Прямо сейчас у Вас просто есть теории, плавающие вокруг в Вашей голове, большинство которых окажется дезинформированным.

Шаг 3: Осуществите рефакторинг беспощадно. Ваша цель должна состоять в том, чтобы удалить приблизительно половину Вашего кода

Вы найдете, что Ваш код в конце или напомнит существующий шаблон разработки, или Вы создадите новый. Вы будете затем квалифицированы для ответа на этот вопрос :-)

21
ответ дан 8 December 2019 в 03:55
поделиться

Стратегическая модель, возможно, один, Вы хотите посмотреть на. Причем стратегия является алгоритмом парсинга файла.

Затем Вы хотите отдельную стратегию вставки базы данных.

1
ответ дан 8 December 2019 в 03:55
поделиться

Я полностью соглашаюсь с Orion Edwards, и это обычно - способ, которым я приближаюсь к проблеме; но в последнее время я начинал видеть некоторые шаблоны (!) к безумию.

Для более сложных задач я обычно использую что-то как интерпретатор (или стратегия), который использует некоторого разработчика (или фабрика) для создания каждой части данных.

Для потоковой передачи данных весь синтаксический анализатор посмотрел бы что-то как адаптер, адаптирующийся от потокового объекта до объектного потока (который обычно является просто очередью).

Для Вашего примера, вероятно, был бы один разработчик для полной структуры данных (от главы к EOF), который внутренне использует разработчиков для внутренних элементов данных (питаемый интерпретатором). После того как с EOF встречаются, объект был бы испущен.

Однако объекты, созданные в операторе переключения в некоторой функции фабрики, являются, вероятно, самым простым путем ко многим меньшим задачам. Кроме того, мне нравится сохранять мои объекты данных неизменными, поскольку Вы никогда не знаете, когда кто-то пихает параллелизм вниз Ваше горло :)

4
ответ дан 8 December 2019 в 03:55
поделиться

Используйте Закон и YACC. Если Вы не посвятите следующие десять лет исключительно этому предмету, они произведут лучше и более быстрый код каждый раз.

1
ответ дан 8 December 2019 в 03:55
поделиться
Другие вопросы по тегам:

Похожие вопросы: