- Can there be other pres inside?
- Is pre always next to td or may there be other text between them?
If the answers are: no, yes, then the expression is:
preg_replace_callback("/(?<!\<td>)<pre>.*?<\/pre>(?!\<\/td>)/is", callback, $text);
If the answers are: no, no, then the expression is:
$RE1="(?:\\s[^>]*)?"; ничего или атрибуты тэга preg_replace_callback("/(<td$RE1>(?:(?!\\<\/td>).)*?)(<pre$RE1>.*?<\/pre>)/is", callback, $text);
In group 1, everything will come from td to pre- this group should be returned to the callback. In the second group, the tag to be processed.
Promised answer:
$text=<<<HEREDOC <td> <td></td> <pre> txt <pre> <td> text </td> </pre> </pre> [] </td> <pre> all okey </pre> <pre></pre> HEREDOC; $RE0="(?:\\s[^>]*)?"; // ничего или атрибуты тэга $RE1="(?P<PRE><pre$RE0>((?:(?!\\<pre$RE0>)(?!\\<\/pre\\s*>).)*+|(?P>PRE))+<\/pre\\s*>)"; $RE2=str_replace("PRE", "TD", str_replace("pre", "td", $RE1)); $text= preg_replace_callback("/$RE1|$RE2/is", "clb", $text); function clb($arr){ if ($arr["TD"]) return $arr["TD"]; // ничего не делаем. побочный результат return "!!!"; } echo htmlspecialchars($text);
Result:
<td> <td></td> <pre> txt <pre> <td> text </td> </pre> </pre> [] </td> !!! !!!