Intereting Posts

preg_replace vs DOMDocument replaceChild

Мне было интересно, какой метод, упомянутый в заголовке, более эффективен для замены содержимого на странице 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'/>

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