0

How could I use RegEx to find <a class="modal> and replace it with <a class="modal-link" ?

I tried:

preg_replace('/<a class="(.*?)">(.*?)<\/a>/i', '<a class="$1-link">$2</a>', $input);

but it's not working. Please can someone point me out to the right solution ?

By the way: I'am styling Joomla 2.5 frontpage edit content page, where the approved user can post an article. That string where i want to apply on my regex comes from:

<?php echo $this->form->getInput('image_intro', 'images'); ?>

it generates this HTML:

<a class="modal" ...>Choose</a>
Andy Lester
  • 91,102
  • 13
  • 100
  • 152
aspirinemaga
  • 3,753
  • 10
  • 52
  • 95
  • 4
    Provide some sample input and explanation on why it's not working - I'm guessing it's because you're trying to find text across multiple lines. Also, are you open to a non-regex solution, as a DOM parser such as DOMDocument would be more appropriate here. – nickb Jan 08 '13 at 19:25
  • can u please tell what's the difference between DOMDocument and RegEx in PHP ? – aspirinemaga Jan 08 '13 at 19:30
  • 1
    I suggest *not* using a regex here. As you posted in the question, the `` tag has more than just a `class` attribute. I suggest using a DOM parser. – gen_Eric Jan 08 '13 at 19:30
  • 1
    @aspirinemaga: DOMDocument is a DOM Parser, like a web browser it actually reads the HTML. RegExes just work on strings in a certain format. HTML doesn't always fit the same format, so RegExes aren't always the best solution. – gen_Eric Jan 08 '13 at 19:31
  • **Don't use regular expressions to parse HTML**. You cannot reliably parse HTML with regular expressions. As soon as the HTML changes from your expectations, your code will be broken. See http://htmlparsing.com/php.html for examples of how to properly parse HTML with PHP modules. – Andy Lester Jan 08 '13 at 19:33
  • That's another let-me-parse-html-with-regex question. It's first in faq: http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags – enrey Jan 08 '13 at 19:36

3 Answers3

6

A non-regex based solution using PHP's DOMDocument class would be:

// Load up the HTML in DOMDocument
$doc = new DOMDocument;
$doc->loadHTML( '<a class="modal">Stuff</a>'); // Or: $doc->loadHTML( $this->form->getInput('image_intro', 'images'));

// Create a new XPath object to find the correct <a> tags
$xpath = new DOMXPath( $doc);

// Iterate over all <a class="modal"> tags
foreach( $xpath->query( "//a[@class='modal']") as $a) {
    // Set the class attribute correctly
    $a->setAttribute( 'class', $a->getAttribute( 'class') . '-link');
    echo $doc->saveHTML( $a); // Print the fixed <a> tag
}

This will output something similar to:

<a class="modal-link">Stuff</a>

This method is more robust and stable than a regular expression based approach, especially if you're getting HTML from user input.

nickb
  • 59,313
  • 13
  • 108
  • 143
  • 1
    Just for completeness, [here](http://codepad.viper-7.com/AWEA5U) is a link to a demo, showing the above code working. – nickb Jan 08 '13 at 19:37
4

Regexp is fine. preg_replace not change $input variable.

Try

$new_string = preg_replace('/<a class="(.*?)">(.*?)<\/a>/i', '<a class="$1-link">$2</a>', $input);

But DON'T USE REGULAR EXPRESSIONS TO PARSE HTML

KryDos
  • 447
  • 4
  • 14
1

There is no way of reliably, or satisfactorily, doing it using regular expressions, but if a crude search-and-replace is okay for what you are doing then it can be done:

$code = '<a class="modal">Choose</a>';
$regex = '/(?<=\sclass=")modal(?="[\s>])/';
echo preg_replace($regex, 'modal-link', $code);

There are at least two reasons that this is a bad idea, through:

  1. You should not parse or modify HTML using regular expressions. Parsing or modifying HTML is not a regular problem, it is a quite complicated and intricate problem. Using regular expressions is like using a sledgehammer when you should be using a chisel.

  2. You should not be modifying HTML code in any case. HTML should just be HTML. If you need your HTML to be different then you should change the HTML at the source, and not try to force it into shape like this.

Sverri M. Olsen
  • 13,055
  • 3
  • 36
  • 52