Regex for matching ALL instances of a specific string in between specific tags

64 Views Asked by At

I'm trying to match/replace all instances of the "br" tag, but only when they're surrounded by the {c} {/c} delimiters. This is the regex pattern I have right now:

/{c}.*(<br>).*{\/c}/mgsU

The problem with what I have currently is that it only matches the very first tag, and ignores the rest, unless there's another {c}{/c} block, where it does the same thing. This is the url to a regex101 page that I've created for testing purposes: https://regex101.com/r/eVI53z/2

It has a test string, and my desired output would be matching lines 2,3,end of 5, beginning of 6 before the {/c} tag, end of line 12, the three tags on line 15, and middle of line 16.

Any help would be greatly appreciated. Thanks, guys!

2

There are 2 best solutions below

1
Babak Asadzadeh On

try this:

{c}(.*(<br>).*){\/c}
0
Barmar On

A regexp can only match one string at a time. You need to do this in two steps:

  1. Match the pattern (?<=\{c\}).*?(?=\{/c\}. This will return everything between {c} and {/c}.

  2. Use preg_match_all with that returned string tofind all the <br> strings in it.

If you're trying to replace into the original string, you can use preg_replace_callback() with the first pattern, then use preg_replace() or str_replace() in the callback function.

$str = '{c}
<br>
<br>
test
test<br>
<br>{/c}
<br>
test
test<br>

{c}
saddasda<br>
{/c}

{c}<br>test<br><br>{/c}
{c}<br>{/c}';
$new_str = preg_replace_callback('#(?<=\{c\}).*?(?=\{/c\})#s', function($matches) {
    return str_replace("<br>", "[linebreak]", $matches[0]);
}, $str);
echo $new_str;

DEMO