Consider the following strings:
targethelloluketestlukeluketestluktestingendtarget
sourcehelloluketestlukeluketestluktestingendsource
I want to replace all instances of luke with something else, but only if it's between target...endtarget, not when it's between source...nonsource. The result should be that all three instances of luke in the top string are replaced with whatever I want.
I got this far, but this will only cap one instance of luke. How do I replace all of them?
(?<=target)(?:.*?(luke).*?)(?=target)
SOLUTION Thanks to the help of this great community, I arrived at the following solution. I find RegEx really convoluted when it comes to this, but in PHP the following works great and is a lot easier to understand:
function replaceBetweenTags($starttag, $endtag, $replace, $with, $text) {
$starttag = escapeStringToRegEx($starttag);
$endtag = escapeStringToRegEx($endtag);
$text = preg_replace_callback(
'/' . $starttag . '.*?' . $endtag . '/',
function ($matches) use ($replace, $with) {
return str_replace($replace, $with, $matches[0]);
},
$text
);
return $text;
}
function escapeStringToRegEx($string)
{
$string = str_replace('\\', '\\\\', $string);
$string = str_replace('.', '\.', $string);
$string = str_replace('^', '\^', $string);
$string = str_replace('$', '\$', $string);
$string = str_replace('*', '\*.', $string);
$string = str_replace('+', '\+', $string);
$string = str_replace('-', '\-', $string);
$string = str_replace('?', '\?', $string);
$string = str_replace('(', '\(', $string);
$string = str_replace(')', '\)', $string);
$string = str_replace('[', '\[', $string);
$string = str_replace(']', '\]', $string);
$string = str_replace('{', '\{', $string);
$string = str_replace('}', '\}', $string);
$string = str_replace('|', '\|', $string);
$string = str_replace(' ', '\s', $string);
$string = str_replace('/', '\/', $string);
return $string;
}
I'm aware of the fact that the escapeStringToRegEx is really quick and dirty, and maybe not even entirely correct, but it's a good starting point to work from.