I would like to replace ">" with ">" and "<" with "<" but only when they occur outside "<pre>" and "</pre>". Is this possible?
$newText = preg_replace('>', '>', $text);
I would be using the preg_replace in PHP as above.
I would like to replace ">" with ">" and "<" with "<" but only when they occur outside "<pre>" and "</pre>". Is this possible?
$newText = preg_replace('>', '>', $text);
I would be using the preg_replace in PHP as above.
I'm not sure offhand if PHP's regex engine does negative lookarounds, but that's what you're interested in. The regex in other languages would look something like:
/(?<!(<pre>[^(<\/pre>)]*))XXX(?!(.*<\/pre>))/
(inhale - I think I have that right)
where XXX is your pattern "<" or ">"
nb. it's likely there's an even simpler pattern too
This isn't really an answer because you asked for a regex, but I just wrote a really dirty function to do it:
<?php
$html = ' <pre>hello > <</pre>
> <
<pre></pre>';
function stringReplaceThing($str) {
$offset = 0;
$num = 0;
$preContents = array();
$length = strlen($str);
//copy string so can maintain offsets/positions in the first string after replacements are made
$str2=$str;
//get next position of <pre> tag
while (false !== ($startPos = stripos($str, '<pre>', $offset))) {
//the end of the opening <pre> tag
$startPos += 5;
//try to get closing tag
$endPos = stripos($str, '</pre>', $startPos);
if ($endPos === false) {
die('unclosed pre tag..');
}
$stringWithinPreTags = substr($str, $startPos, $endPos - $startPos);
//replace string within tags with some sort of token
if (strlen($stringWithinPreTags)) {
$token = "!!T{$num}!!";
$str2 = str_replace($stringWithinPreTags, $token, $str2);
$preContents[$token] = $stringWithinPreTags;
$num++;
}
$offset = $endPos + 5;
}
//do the actual replacement
$str2 = str_replace(array('>', '<'), array('>', '<'), $str2);
//put the contents of <pre></pre> blocks back in
$str2 = str_replace(array_keys($preContents), array_values($preContents), $str2);
return $str2;
}
print stringReplaceThing($html);
If you want to do this with a regex, the trick is to make your regex match the things you don't want to replace as well as the things you want to replace, and dynamically calculate the replacement depending on what was matched.
$new_text = preg_replace_callback('%<|>|<pre>.*?</pre>%si', compute_replacement, $text);
function compute_replacement($groups) {
if ($groups[0] == '<') {
return '<';
} elseif ($groups[1] == '>') {
return '>';
} else {
return $groups[0];
}
}