Expresiones regulares lentas.
Hola. Tengo una web sobre programación en cuyos foros normalmente se postea gran cantidad de código ya sea c++, html o cualquier cosa. El problema es que debo permitir que se incluyan algunas etiquetas HTML mientras que otras debo borrarlas. Además debo utilizar la función nl2br para que el texto se muestre correctamente.
He definido una etiqueta llamada code (<code>) dentro de la cual las etiquetas HTML no se eliminan pero tampoco se interpretan, sino que se muestran tal cual. Para ello utilizo expresiones regulares. El problema es que cuando los textos son relativamente largos, la página tarda 15 o 20 segundos en mostrarse. Os paso el código problemático:
function prepara_texto($datos)
{
//Primero buscamos la etiqueta especial <code> y </code> y entre ellas cambiamos los < y > por < y >
while ( eregi ( "(.*)(<code>)(.*)(</code>)(.*)" ,$datos,$datos_1))
{
$datos_1[3] = strtr(
$datos_1[3],
array(
"<" => "<" ,
">" => ">"
)
);
$datos=$datos_1[1]."<&coded%>".$datos_1[3]."</&coded%>".$datos_1[5];
}
//Ya tenemos salvados los code y la nueva etiqueta <&coded%> y </&coded%>
//Ahora reemplazamos << y >> por < y >
$datos = strtr($datos,
array("<<" => "<" ,
">>" => ">" )
);
//Ahora eliminamos las cadenas que no nos interesan y salvamos las demás. Además cambiamos los intros por <BR>
$datos =nl2br(strip_tags($datos, '><i><u><b><a><&coded%><LI><UL><OL><DL><DH><DD><DT><H1><H2><H3><H4><H5><H6><')) ;
//Ahora hacemos que los hipervinculos salten fuera
$datos =strtr($datos,array("HREF=" => "target=_blank HREF=" ,
"Href=" => "target=_blank HREF=" ,
"href=" => "target=_blank HREF=" ,
"HRef=" => "target=_blank HREF=") );
//Ahora cambiamos la etiqueta coded por un font y salvamos los espacions
$datos =strtr($datos,
array("<&coded%>" => "<font class=CodedFont>" ,
"</&coded%>" => "</font>" ,
" " => " "
)
);
return $datos;
}
¿¿Alguna sugerencia??
He definido una etiqueta llamada code (<code>) dentro de la cual las etiquetas HTML no se eliminan pero tampoco se interpretan, sino que se muestran tal cual. Para ello utilizo expresiones regulares. El problema es que cuando los textos son relativamente largos, la página tarda 15 o 20 segundos en mostrarse. Os paso el código problemático:
function prepara_texto($datos)
{
//Primero buscamos la etiqueta especial <code> y </code> y entre ellas cambiamos los < y > por < y >
while ( eregi ( "(.*)(<code>)(.*)(</code>)(.*)" ,$datos,$datos_1))
{
$datos_1[3] = strtr(
$datos_1[3],
array(
"<" => "<" ,
">" => ">"
)
);
$datos=$datos_1[1]."<&coded%>".$datos_1[3]."</&coded%>".$datos_1[5];
}
//Ya tenemos salvados los code y la nueva etiqueta <&coded%> y </&coded%>
//Ahora reemplazamos << y >> por < y >
$datos = strtr($datos,
array("<<" => "<" ,
">>" => ">" )
);
//Ahora eliminamos las cadenas que no nos interesan y salvamos las demás. Además cambiamos los intros por <BR>
$datos =nl2br(strip_tags($datos, '><i><u><b><a><&coded%><LI><UL><OL><DL><DH><DD><DT><H1><H2><H3><H4><H5><H6><')) ;
//Ahora hacemos que los hipervinculos salten fuera
$datos =strtr($datos,array("HREF=" => "target=_blank HREF=" ,
"Href=" => "target=_blank HREF=" ,
"href=" => "target=_blank HREF=" ,
"HRef=" => "target=_blank HREF=") );
//Ahora cambiamos la etiqueta coded por un font y salvamos los espacions
$datos =strtr($datos,
array("<&coded%>" => "<font class=CodedFont>" ,
"</&coded%>" => "</font>" ,
" " => " "
)
);
return $datos;
}
¿¿Alguna sugerencia??
He olvidado decir que lo que causa el problema es el primer while.
¿Alquien sabe de algún sitio donde tengan hecho algo similar?
¿Saben si sepodrÃa hacer un programa compilado con algún otro lenguaje que fuese más rápido, y leugo ejecutarlo desde PHP y obtener la salida? ¿Seria globalmente más rápido, aunque hubiese que trabajar incluso con ficheros de por medio para enviar la entrada al programa?
Gracias
¿Alquien sabe de algún sitio donde tengan hecho algo similar?
¿Saben si sepodrÃa hacer un programa compilado con algún otro lenguaje que fuese más rápido, y leugo ejecutarlo desde PHP y obtener la salida? ¿Seria globalmente más rápido, aunque hubiese que trabajar incluso con ficheros de por medio para enviar la entrada al programa?
Gracias
Ya lo he conseguido.
Lo he hecho con el mismo algoritmo, pero cambiando la función eregi por una de perl:
function prepara_texto($datos)
{
//Primero buscamos la etiqueta especial <code> y </code> y entre ellas cambiamos los < y > por < y >
while(preg_match_all ("|(.*)(<CODE>)(.*)(</CODE>)(.*)|is", $datos, $matches))
{
$matches[3][0]=strtr(
$matches[3][0],
array(
"<" => "<" ,
">" => ">"
)
);
$datos=$matches[1][0]."<&coded%>".$matches[3][0]."</&coded%>".$matches[5][0];
}
//Ya tenemos salvados los code y la nueva etiqueta <&coded%> y </&coded%>
//Ahora reemplazamos << y >> por < y >
$datos = strtr($datos,
array("<<" => "<" ,
">>" => ">" )
);
//Ahora eliminamos las cadenas que no nos interesan y salvamos las demás. Además cambiamos los intros por <BR>
$datos =nl2br(strip_tags($datos, '><i><u><b><a><&coded%><LI><UL><OL><DL><DH><DD><DT><H1><H2><H3><H4><H5><H6><')) ;
//Ahora hacemos que los hipervinculos salten fuera
$datos =strtr($datos,array("HREF=" => "target=_blank HREF=" ,
"Href=" => "target=_blank HREF=" ,
"href=" => "target=_blank HREF=" ,
"HRef=" => "target=_blank HREF=") );
//Ahora cambiamos la etiqueta coded por un font y salvamos los espacions
$datos =strtr($datos,
array("<&coded%>" => "<font class=CodedFont>" ,
"</&coded%>" => "</font>" ,
" " => " "
)
);
return $datos;
}
Lo he hecho con el mismo algoritmo, pero cambiando la función eregi por una de perl:
function prepara_texto($datos)
{
//Primero buscamos la etiqueta especial <code> y </code> y entre ellas cambiamos los < y > por < y >
while(preg_match_all ("|(.*)(<CODE>)(.*)(</CODE>)(.*)|is", $datos, $matches))
{
$matches[3][0]=strtr(
$matches[3][0],
array(
"<" => "<" ,
">" => ">"
)
);
$datos=$matches[1][0]."<&coded%>".$matches[3][0]."</&coded%>".$matches[5][0];
}
//Ya tenemos salvados los code y la nueva etiqueta <&coded%> y </&coded%>
//Ahora reemplazamos << y >> por < y >
$datos = strtr($datos,
array("<<" => "<" ,
">>" => ">" )
);
//Ahora eliminamos las cadenas que no nos interesan y salvamos las demás. Además cambiamos los intros por <BR>
$datos =nl2br(strip_tags($datos, '><i><u><b><a><&coded%><LI><UL><OL><DL><DH><DD><DT><H1><H2><H3><H4><H5><H6><')) ;
//Ahora hacemos que los hipervinculos salten fuera
$datos =strtr($datos,array("HREF=" => "target=_blank HREF=" ,
"Href=" => "target=_blank HREF=" ,
"href=" => "target=_blank HREF=" ,
"HRef=" => "target=_blank HREF=") );
//Ahora cambiamos la etiqueta coded por un font y salvamos los espacions
$datos =strtr($datos,
array("<&coded%>" => "<font class=CodedFont>" ,
"</&coded%>" => "</font>" ,
" " => " "
)
);
return $datos;
}
