preg_replace против DOMDocument replaceChild

Мне было интересно, какой метод, упомянутый в заголовке, более эффективен для замены содержимого на html-странице.

У меня есть этот пользовательский тег на моей странице: <includes module='footer'/>, который будет заменен некоторым контентом.

Теперь есть некоторые недостатки с использованием DOMDocument->getElementsByTagName('includes')->item(0)->parentNode->replaceChild, например, когда я забыл добавить косую черту в тег, например, <includes module='footer'> весь сайт падает.

Regex допускает подобные исключения, если они соответствуют правилу. Это даже позволило бы мне заменить любую строку, например {includes:footer}.

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

Подробнее здесь: Добавить дочерний элемент/элемент в голову с помощью XML-манипуляции

ваше здоровье


person domizai    schedule 23.05.2014    source источник


Ответы (2)


Я бы не слишком беспокоился о производительности здесь, я бы считал их «сопоставимыми». Чтобы точно определить это, необходимо будет выполнить тесты, поскольку это будет зависеть от размера документа и того, как написано регулярное выражение.

Вместо этого я бы беспокоился о точности. В целом DOMDocument будет намного лучше анализировать XML, поскольку он был создан для чтения и понимания языка. Однако он не работает с <includes module='footer'>, потому что это незакрытый тег (ожидается: </includes>).

Наиболее распространенные проблемы с форматированием HTML/XML можно исправить с помощью PHP-класса Tidy. . Я бы проверил это, так как вы должны получить гораздо больше ">"ожидаемые результаты" по сравнению с использованием регулярного выражения для синтаксического анализа. Если вы использовали регулярное выражение, технически могут быть атрибуты до/после module, элементы внутри элемента includes, неожиданные символы, такие как <includes module='foo>bar'> и т. д.

В конце концов, если ваш XML находится в «контролируемой» среде (т.е. вы знаете, что может и не может произойти, вы знаете, какие возможные символы будет содержать module, вы знаете, что это всегда будет самозакрывающийся элемент, содержащий теперь дочерние элементы, и т. д.), чем во что бы то ни стало использовать регулярное выражение. Просто знайте, что он ищет очень конкретный набор правил. Однако, если вы ожидаете, что это будет работать с «всем, что вы бросите в него».. пожалуйста, используйте синтаксический анализатор DOM (после Tidy, чтобы избежать исключений), независимо от производительности (хотя я уверен, что во многих случаях это будет очень сопоставимо ).

Кроме того, последнее замечание: если вы планируете находить/заменять/манипулировать многими узлами в документе, вы увидите значительное увеличение производительности при использовании парсера DOM. Анализатор DOM возьмет документ и проанализирует его один раз. Затем вы просто просматриваете данные, которые он уже загрузил в свой класс. Это можно сравнить с использованием регулярных выражений, где каждое отдельное выражение будет просматриваться по всему документу в поисках набора совпадений.

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

person Sam    schedule 23.05.2014
comment
Эй, это действительно подробный ответ! Я думаю, что я выберу DOMDocument и Tidy, потому что я еще не очень разбираюсь в регулярных выражениях. Если у меня возникнут проблемы, я дам вам знать ;) - person domizai; 23.05.2014
comment
Нет проблем, если у вас возникнут проблемы с Tidy, дайте мне знать. Если я правильно помню, у него масса параметров конфигурации и он работает с XML< /а>. Я определенно думаю, что DOMDocument - правильный путь, хотя всегда весело возиться с регулярным выражением;) - person Sam; 23.05.2014

Итак, я провел наивное тестирование производительности, используя microtime (true). И оказывается, что использование preg_replace — более быстрый вариант. В то время как DOM replaceChild требовалось от 2,0 до 3,5 мс, preg_replace требовалось от 0,5 до 1,2 мс! Но я думаю, это только в моем случае.

Вот как выглядит мой html:

<!DOCTYPE html>
<html>
    <head>
        {includes:title}
        {includes:style}
    </head>
    <body>
        {includes:body}
        {includes:footer}
        ...
        allot more here
        ...
    </body>
</html>

это регулярное выражение используется: /{([ ]*)includes:([ ]*)$key([^}]*)}/i

Как я уже сказал, я не полностью разбираюсь в использовании регулярных выражений, но это сработало. Думаю, если вы оптимизируете его, он будет работать еще быстрее.

Для метода replaceChild я использовал такой собственный тег: <includes module='body'/>

Опять же, это тест на моем локальном сервере, поэтому мне все еще нужно проверить, как он будет вести себя на моем онлайн-сервере...

person domizai    schedule 24.05.2014