Мне было интересно, какой метод, упомянутый в заголовке, более эффективен для замены содержимого на странице html.
У меня есть этот пользовательский тег на моей странице: <includes module='footer'/>
который будет заменен некоторым контентом.
Теперь есть некоторые недостатки с использованием DOMDocument->getElementsByTagName('includes')->item(0)->parentNode->replaceChild
например, когда я забыл добавить косую черту в теге, например <includes module='footer'>
DOMDocument->getElementsByTagName('includes')->item(0)->parentNode->replaceChild
<includes module='footer'>
происходит сбой всего сайта.
Regex допускает такие исключения, если они соответствуют правилу. Это даже позволило бы мне заменить любую строку, например {includes:footer}
.
Теперь вернемся к моему фактическому вопросу. Есть ли недостатки, использующие регулярное выражение для этой цели, например проблемы с производительностью …?
Подробнее здесь: Добавить дочерний элемент в голову с помощью XML-манипуляции
ура
Я бы не стал слишком беспокоиться о производительности здесь, я бы счел их «сопоставимыми». Тесты должны быть проверены, чтобы действительно определить это, поскольку это будет зависеть от размера документа и того, как написано регулярное выражение.
Вместо этого меня беспокоит точность. В целом DOMDocument
будет намного лучше DOMDocument
XML, поскольку он был построен для чтения и понимания языка. Однако он не работает в <includes module='footer'>
потому что это незакрытый тег (ожидающий: </includes>
).
Наиболее распространенные проблемы форматирования HTML / XML могут быть исправлены с помощью класса Tidy
PHP. Я бы это выяснил, так как вы должны получать гораздо больше «ожидаемых результатов» по сравнению с использованием регулярного выражения для синтаксического анализа. Если вы использовали регулярное выражение, технически могут быть атрибуты до / после module
, элементы внутри элемента include, неожиданные символы, такие как <includes module='foo>bar'>
и т. Д.
В конце концов, если ваш XML находится в «контролируемой» среде (т. Е. Вы знаете, что может и не может произойти, вы знаете, какой module
возможных символов будет содержать, вы знаете, что он всегда будет элементом самозакрывания, содержащим теперь детей, и т. д.), чем во что бы то ни стало, используйте регулярное выражение. Просто знайте, что он ищет очень специфический набор правил. Однако, если вы ожидаете, что это будет работать с «чем-нибудь, что вы на него набросите» .. пожалуйста, используйте парсер DOM (после Tidy
, чтобы избежать исключений), независимо от производительности (хотя я уверен, что это будет очень сопоставимо во многих случаях ).
Кроме того, последнее замечание: если вы планируете находить / заменять / манипулировать многими узлами в документе, вы увидите значительное увеличение производительности, перейдя с парсером DOM. Парсер DOM возьмет документ и проанализирует его один раз. Затем вы просто проходите данные, которые он уже загрузил в свой класс. Это сравнивается с использованием регулярных выражений, в которых каждый отдельный пользователь будет сталкиваться со всем документом, ища набор совпадений.
Если вы хотите, чтобы я стал более конкретным в любой области (например, дайте пример Tidy
или работайте над эталоном ), дайте мне знать.
Поэтому я сделал несколько наивных тестов производительности, используя 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>
в<!DOCTYPE html> <html> <head> {includes:title} {includes:style} </head> <body> {includes:body} {includes:footer} ... allot more here ... </body> </html>
в<!DOCTYPE html> <html> <head> {includes:title} {includes:style} </head> <body> {includes:body} {includes:footer} ... allot more here ... </body> </html>
в<!DOCTYPE html> <html> <head> {includes:title} {includes:style} </head> <body> {includes:body} {includes:footer} ... allot more here ... </body> </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'/>
Опять же, это тест на моем локальном сервере, поэтому мне все равно нужно сделать некоторые тесты о том, как он будет вести себя на моем онлайн-сервере …