2009-05-11 11 views
5

Necesito reemplazar todo & en una cadena que no sea parte de una entidad HTML. De manera que la cadena "Este & ENTIDADES > & <" volverán "Este & ENTIDADES > & <"Optimización de expresiones regulares - escapando entre símbolos en java

Y se me ha ocurrido con esta expresión regular-patrón: "& [a-zA-Z0-9] {2 , 7}; "que funciona bien. Pero no soy muy hábil en expresiones regulares, y cuando pruebo la velocidad en iteraciones de 100k, usa una cantidad de tiempo doble sobre un método usado anterior, que no usó expresiones regulares. (Pero tampoco funcionaba al 100%).

Testcode:

long time = System.currentTimeMillis(); 
String reg = "&(?!&#?[a-zA-Z0-9]{2,7};)"; 
String s="a regex test 1 & 2 1&2 and &_gt; - &_lt;" 
for (int i = 0; i < 100000; i++) {test=s.replaceAll(reg, "&amp;");} 
System.out.println("Finished in:" + (System.currentTimeMillis() - time) + " milliseconds"); 

Entonces la pregunta sería si hay algunas maneras obvias de optimizar esta expresión expresiones regulares para que sea más eficaz?

+0

que tenía que escribir las ENTIDADES con guión bajo como &_gt; o de lo contrario iba a presentar como el símbolo del código era. – Duveit

+0

Casi cuatro de nosotros hemos intentado editar su texto para rodear los signos y signos de formato de código. Solo seleccione el texto que desee y use el código, retendrá el símbolo comercial. – cgp

Respuesta

6

s.replaceAll(reg, "&amp;") está compilando la expresión regular todo el tiempo. Compilar el patrón una vez proporcionará cierto aumento en el rendimiento (~ 30% en este caso).

long time = System.currentTimeMillis(); 
String reg = "&(?!&#?[a-zA-Z0-9]{2,7};)"; 
Pattern p = Pattern.compile(reg); 
String s="a regex test 1 & 2 1&2 and &_gt; - &_lt;"; 
for (int i = 0; i < 100000; i++) { 
    String test = p.matcher(s).replaceAll("&amp;"); 
} 
System.out.println("Finished in:" + 
      (System.currentTimeMillis() - time) + " milliseconds"); 
+0

Eso es verdad, bajó de 550 ms a 450 ms. Veré si podemos implementar el patrón precompilado. – Duveit

0

No estoy muy familiarizado con las clases de expresiones regulares de Java, pero en general es posible que desee investigar una búsqueda de ancho cero; después del signo y.

Here is a link que describen los símbolos de anticipación positivos y negativos

+0

Esta es la página que he estado viendo cuando hice esto, de hecho :), eché un vistazo a lookaheads positivos y negativos, pero los cambios que intenté no aumentaron la eficiencia. – Duveit

1

Otra forma de hacer esto wihtout sonarse la cabeza con expresión regular sería utilizar StringEscapeUtils de Commons Lang.

+0

Estamos usando partes de esta biblioteca, sin embargo, solo tenemos que arreglar ampersands en este caso. Y tiene que aceptar una cadena que puede ser una combinación de entidades y '&' simples. - Gracias, sin embargo. – Duveit

2

Tiene que excluir el & de su afirmación de anticipación. Así que trate de esta expresión regular:

&(?!#?[a-zA-Z0-9]{2,7};) 

O para ser más precisos:

&(?!(?:#(?:[xX][0-9a-fA-F]|[0-9]+)|[a-zA-Z]+);) 
Cuestiones relacionadas