Search code examples
preg-replacepreg-replace-callback

Find <p> elements in HTML body and insert <span> tags


I have a HTML file, for example:

<p class="label" id="p-1'>This is my sample txt </p>
<p class="label" id="p-2'>This is my sample txt </p>
<p class="label" id="p-3'>This is my sample txt </p>
<p class="label" id="p-4'>This is my sample txt </p>
<p class="label" id="p-5'>This is my sample txt </p>

I want the output look like this:

<p class="label" id="p-1'><span class ="span-class">This is my sample txt </span></p>
<p class="label" id="p-2'><span class ="span-class">This is my sample txt </span></p>
<p class="label" id="p-3'><span class ="span-class">This is my sample txt </span></p>
<p class="label" id="p-4'><span class ="span-class">This is my sample txt </span></p>
<p class="label" id="p-5'><span class ="span-class">This is my sample txt </span></p>

Is this possible with preg_replace? Is there any other way to accomplish this?


Solution

  • In php you can achieve this with:

    <?php
    
    $html = <<< LOB
    <p class="label" id="p-1'>This is my sample txt </p>
    <p class="label" id="p-2'>This is my sample txt </p>
    <p class="label" id="p-3'>This is my sample txt </p>
    <p class="label" id="p-4'>This is my sample txt </p>
    <p class="label" id="p-5'>This is my sample txt </p>
    LOB;
    
    echo preg_replace('%<p class="label" id="p-(.*?)\'>(.*?)</p>%sim', '<p class="label" id="p-$1\'><span class ="span-class">$2</span></p>', $html);
    
    ?>
    

    EXPLANATION:

    <p class="label" id="p-(.*?)'>(.*?)</p>
    
    Options: Case insensitive; Exact spacing; Dot matches line breaks; ^$ match at line breaks; Greedy quantifiers; Regex syntax only
    
    Match the character string “<p class="label" id="p-” literally (case insensitive) «<p class="label" id="p-»
    Match the regex below and capture its match into backreference number 1 «(.*?)»
       Match any single character «.*?»
          Between zero and unlimited times, as few times as possible, expanding as needed (lazy) «*?»
    Match the character string “'>” literally «'>»
    Match the regex below and capture its match into backreference number 2 «(.*?)»
       Match any single character «.*?»
          Between zero and unlimited times, as few times as possible, expanding as needed (lazy) «*?»
    Match the character string “</p>” literally (case insensitive) «</p>»
    
    <p class="label" id="p-$1'><span class ="span-class">$2</span></p>
    
    Insert the character string “<p class="label" id="p-” literally «<p class="label" id="p-»
    Insert the text that was last matched by capturing group number 1 «$1»
    Insert the character string “'><span class ="span-class">” literally «'><span class ="span-class">»
    Insert the text that was last matched by capturing group number 2 «$2»
    Insert the character string “</span></p>” literally «</span></p>»
    

    DEMO: http://ideone.com/YaZG2p