2012-10-09 11 views
5

Estoy tratando de crear una expresión regular para mi problema y aparentemente encontré un problema extraño.Java Regex lookahead toma demasiado tiempo

Vamos a describir lo que estoy tratando de hacer ..

Mi objetivo es eliminar las comas de ambos extremos de la cadena. E, g, string , ,, ,,, , , Hello, my lovely, world, ,, , debería convertirse en solo Hello, my lovely, world.

he preparado siguiente expresión regular para lograr esto: (\w+,*? *?)+(?=(,?\W+$))

Funciona como un encanto en validadores de expresiones regulares, pero cuando estoy tratando de ejecutarlo en el dispositivo Android, matcher.find() función cuelga durante ~ 1 minuto para encontrar una combinación apropiada ... supongo, el problema está en búsqueda positiva hacia delante que estoy usando, pero no pude encontrar ninguna solución mejor que simplemente recortar comas separado desde el principio y al final:

output = input.replaceAll("^(,?\\W?)+", ""); //replace commas at the beginning 
output = output.replaceAll("(,?\\W?)+$", ""); //replace commas at the end 

es hay algo que me falta en positivo mira hacia adelante i n Java regex? ¿Cómo puedo recuperar la sección de cadena entre las comas al principio y al final?

Respuesta

8

No tiene que usar una búsqueda anticipada si usa grupos coincidentes. Trate de expresiones regulares ^[\s,]*(.+?)[\s,]*$:

EDIT: Para romperlo, ^ coincide con el inicio de la línea, que técnicamente es redundante si se utiliza matches() pero puede ser útil en otros lugares. [\s,]* coincide con cero o más caracteres en blanco o comas, pero con avidez: aceptará la mayor cantidad de caracteres posible. (.+?) coincide con cualquier cadena de caracteres, pero el signo de interrogación final indica que coincida con la menor cantidad de caracteres posible (no codiciosos), y también captura los contenidos en el "grupo 1", ya que forma el primer conjunto de paréntesis. La coincidencia no codiciosa permite que el grupo final contenga las mismas cero o más comas o espacios en blanco ([\s,]*). Al igual que el ^, el $ final coincide con el final de la línea, útil para find() pero redundante para matches().

Si necesita que coincida con espacios solamente, reemplace [\s,] con [ ,].

Esto debería funcionar:

Pattern pattern = Pattern.compile("^[\\s,]*(.+?)[\\s,]*$"); 
Matcher matcher = pattern.matcher(", ,, ,,, , , Hello, my lovely, world, ,, ,"); 
if (!matcher.matches()) 
    return null; 
return matcher.group(1); // "Hello, my lovely, world" 
+0

arghh ... ¿cómo podría perderse grupos que coinciden .. :(Muchas gracias llegué a refrescar mis conocimientos de expresiones regulares ... –