3
\$\begingroup\$

I am new using regex expression. After much digging I came up with this code. I would like to know if this is the correct way. I want to search in Joomla for some html tags with specific class and then replace the code between those tags. I want to use an array ($patterns) with tag and classes and another array ($replacements) with replacements values.

$body = JResponse::getBody();
$patterns = array
(
array('a','logo')
array('span','main')
);

$replacements = array
(
array('<p>some text</p>')
array('<p>another text</p>')
);

foreach ($patterns as $key => $value) {
$body = preg_replace('/(<'.$patterns[$key][0].' .*?class=".*?'.$patterns[$key][1].'.*?">)(.*?)(<\/'.$patterns[$key][0].'>)/', '$1'.$replacements[$key][0].'$3', $body); 
    }
\$\endgroup\$
1

1 Answer 1

2
\$\begingroup\$

This is never going to work

HTML uses tags that are nested. So if you are looking for pattern array('ul','nicelist') in the following bit, it will fail:

<ul class="nicelist">
  <li>item 1</li>
  <li>item 2
    <ul class="nicesublist">
      <li>subitem 1</li>
      <li>subitem 2</li>
      <li>subitem 3</li>
    </ul>
  </li>
  <li>item 3</li>
  <li>item 4</li>
</ul>

You can see it will hit the wrong </ul>. So your solution is not general enough.

The only good way to manipulate HTML in PHP is to use code that understands the DOM. See:

http://php.net/manual/en/domdocument.loadhtml.php

or:

http://sourceforge.net/projects/simplehtmldom/files

These were made to do the things you try to do with preg_replace().

As for your code itself: I am baffled by the seperation between patterns and the replacements. Why not make one array like:

$replacements = [['tag' => 'a',    'class' => 'logo', 'insert' => '<p>some text</p>'],
                 ['tag' => 'span', 'class' => 'main', 'insert' => '<p>another text</p>']];

Keep things together that belong together. I've also used the new array syntax, you need PHP 5.4 or higher, I think, and added keys. The keys make your code better readable, especially if you revisit the code after some time.

I will not go into the reasons why it's a bad idea to do what you're trying to do, replacings pieces of HTML like this, even if you were to use the DOM. I guess there can be some situations in which this is needed?

\$\endgroup\$
2
  • \$\begingroup\$ I know that probably this is not a good approach but i am making some testing and learning. Thank you for your advices \$\endgroup\$
    – n.h.
    Sep 24, 2014 at 21:40
  • \$\begingroup\$ You're welcome. But please only post code you want serious peer review on, not some test you more-or-less know to be faulty. This way we can't help you to learn RegEx. \$\endgroup\$ Sep 24, 2014 at 21:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.