Hi,

I was wondering how I'd turn

$html = '<p><img scr="some-url.jpg" /></p><p>text</p>';

into

$html_new = '<img scr="some-url.jpg" /><p>text</p>';

using regular expressions, i.e., how can the first p tags can be removed?

    I guess this is it.

    $regExp = "/<p>.*(<img.*?)<\/p>(.*)/e";
    $matches = preg_replace ($regExp, "'\\1'.'\\2'", $content);
    

      Yes, that looks good.
      Hope it works.
      If not, there are some people here very good with regex.

        The /e is unnecesssary, and you can limit how many replacements preg_replace will do:

        $regExp = "/<p>.*(<img.*?)<\/p>/";
        $matches = preg_replace ($regExp, "\\1", $content, 1); 
        

          That's nice to know.
          Thank you very much!

            Typically, it isn't a good idea to use .*, as depending on the target string in question, the dot_match_all wild card might match more than you want. Since the star quantifier is greedy, it will match everything that it can (via the star), then backtrack. You hope that the backtracking stops at the correct <img part.

            For example, assuming from the next snippet we want to match the first img tag.. that initial .* part in the pattern throws a wrench in the cogs so to speak:

            $content = '<p>This is a test with an image: <img src="someFolderToSomeImage/someImage.gif" /></p><p>This is a another test: <img src="someFolderToSomeImage2/someImage2.gif" /></p>';
            preg_match('/<p>.*(<img.*?)<\/p>/', $content, $match);
            echo $match[1]; // hopefully you wanted the second img tag and not the first!
            

            Generally, it is wiser to make quantifiers in these situations lazy (via .*?). But like anything else, it is circumstancial. Just that in cases like this, using greedy quantifiers could potentially give inaccurate results. An even better solution would be to use Dom / XPath, but I digress.

              hi nrg_alpha,

              Thanks for pointing that out.

              Now I have

              $content = '<p>This is a test with an image: <img src="someFolderToSomeImage/someImage.gif" /></p><p>This is a another test: <img src="someFolderToSomeImage2/someImage2.gif" /></p>';
              preg_match('/<p>.*?(<img.*?)<\/p>/', $content, $match);
              echo $match[1];
              
                7 months later

                Hi there! Thanks for all the interesting input. I'm just about to make myself ridiculous, probably, at least. But as a php rookie I need to solve a problem I just don't know how to tackle:
                My db returns $body enclosed by a <p>. Something like <p>blah</p>. My problem is that I want to inject an other varible ($created) in front. How can i get rid of the <p>? I could also remove the first and last tag and re-add it with my function. Something like: <p><i>$created - </i>$body</p> but cannot know how many paragraphs there are.
                Any help is greatly apreciated, it just drives me nuts... Thanks in advance!

                  Like nrg_alpha pointed out, use DOM.

                    Write a Reply...