hay que ver la funcion... por que en realidad, no hay forma de que PHP "escape" por si solo entidades HTML, ya que tu codigo puede hacerlo y tu ni en cuenta....
la otra, es mas sencilla... para lograrlo debes o puedes usar mas funciones, no simples replace...
Código PHP:
<?php
function test1($match)
{
$tmp = explode('|', $match[1]);
$tmp = join('</td><td>', $tmp); // OK ?
/*
observa que la salida es siempre
una fila... incluso, lleva una sola
columna... para permitir a la
funcion "test1" completar
con logia el patron
*/
return "<tr><td>$tmp</td></tr>";
}
$str = '[tabla]
[fila]Columna1Fila1 | Columna2Fila1 | Columna3Fila1[/fila]
[fila]Columna1Fila2 | Columna2Fila2 | Columna3Fila2[/fila]
[/tabla]';
// esta debe ser tu expresion... supongo (s = entre lineas)
$test = preg_replace('/\[tabla\](.+?)\[\/tabla\]/is', '<table>\\1</table>', $str);
// por filas (m = multilinea)
$test = preg_replace_callback('/\[fila\](.+?)\[\/fila\]/im', 'test1', $test);
// resultado
echo "$test <hr /> <pre>$str</pre>";
?>
suerte!