Search code examples
phpregexpreg-replacepreg-replace-callback

Find all matches between delimeters


How do I replace all <p> tags between delimiters? My text is

<p>other text...</p>
<p>other text...</p>
``text text...</p>
<p>text text...</p>
<p>text text ...``
<p>other text...</p>
<p>other text...</p>
``text text...</p>
<p>text text...</p>
<p>text text ...``
<p>other text...</p>
<p>other text...</p>
``text text...</p>
<p>text text...</p>
<p>text text ...``
<p>other text...</p>
<p>other text...</p>

I want to match all <p> tags between double backticks (``all p tags here``) as delimiters and replace them with empty string. I could match p tags if there is no other text outside delimiters using regex /<\/?p>/i but how can I match all p tags inside delimiters if there is text and other p tags outside them.


Solution

  • This is a job for preg_replace_callback:

    $str = <<<EOD
    <p>other text...</p>
    <p>other text...</p>
    ``text text...</p>
    <p>text text...</p>
    <p>text text ...``
    <p>other text...</p>
    <p>other text...</p>
    ``text text...</p>
    <p>text text...</p>
    <p>text text ...``
    <p>other text...</p>
    <p>other text...</p>
    ``text text...</p>
    <p>text text...</p>
    <p>text text ...``
    <p>other text...</p>
    <p>other text...</p>
    EOD;
    
    $res = preg_replace_callback(
            '/``(?:(?!``).)*``/s', 
            function ($m) {
                return preg_replace('~</?p>~', '', $m[0]);
            },
            $str);
    echo $res;
    

    Output:

    <p>other text...</p>
    <p>other text...</p>
    ``text text...
    text text...
    text text ...``
    <p>other text...</p>
    <p>other text...</p>
    ``text text...
    text text...
    text text ...``
    <p>other text...</p>
    <p>other text...</p>
    ``text text...
    text text...
    text text ...``
    <p>other text...</p>
    <p>other text...</p>