Regex para eliminar espacios dentro del texto citado

Necesito eliminar todos los espacios en blanco solo dentro de las secciones citadas de una cadena.

Da esto: 10 00,400,"a1 b2 c3 ",zz xx,100

Necesito este: 10 00,400,"a1b2c3",zz xx,100

Obviamente, restringirlo solo a las áreas citadas es la razón por la que tengo problemas.

Las cadenas variarán en longitud y pueden tener varias secciones citadas.

preguntado el 22 de mayo de 12 a las 18:05

¿Manejas tienen usar una expresión regular? -

No, pero sería mucho más fácil si pudiera debido a algunos factores ambientales limitantes. -

¿Existe un límite para la cantidad de secciones que no son espacios dentro de las comillas? Como en el ejemplo, ¿siempre habrá 3 secciones de texto entre comillas? -

algo como ((^|,)\")(.+?)?\s+(.+?)?(?=\"($|,)) -

@Sheriff sin límite, podría ser cualquier cosa =( -

3 Respuestas

No usa expresiones regulares, pero funciona

public String replaceWithinQuotes(String input) {
    String[] output = input.split("\"");
    StringBuilder builder = new StringBuilder();
    for ( int i =0; i < output.length-1; i++ ) {
        if ( i %2 == 0 ) {
            builder.append(output[i]);
        } else {
            builder.append(output[i].replaceAll("[ ]+", ""));
        }
        builder.append("\"");
    }
    builder.append(output[output.length-1]);
    return builder.toString();
}

Nota: si está utilizando esto, asegúrese de que la longitud de la matriz sea impar. Si no es así, entonces tiene cotizaciones desequilibradas y debe manejarlas de la manera que sea apropiada para su aplicación.

contestado el 22 de mayo de 12 a las 19:05

La función no sabe si es dentro una sección citada. Solo sabe que encontró una cita. - Piedra de Luna

@DanielE: reemplaza solo las entradas "impares", por lo que está dentro. Sin embargo, debe agregar el manejo de errores para cotizaciones desequilibradas. - Viruta

Suponiendo que las cotizaciones estén equilibradas, podría implementar un método como este:

public static void main(String[] args) {

    String str = "10 00,400,\"a1 b2 c3 \",zz xx,100, \"a b\"";
    StringBuffer sb = new StringBuffer();

    Matcher matcher = Pattern.compile("\"([^\"]+)\"").matcher(str);
    while (matcher.find()) {
        matcher.appendReplacement(sb, matcher.group().replaceAll("\\s+", ""));
    }

    System.out.println(sb.toString());
}

Esto imprime:

10 00,400,"a1b2c3",zz xx,100, "ab"

contestado el 22 de mayo de 12 a las 19:05

Gracias, lo probaré. - Piedra de Luna

Hmm, está cortando el último de la cadena cuando se usa una entrada que no termina en una comilla. ¿Cuál es la forma más elegante de acceder al último "delimitador" en ese búfer de coincidencia? - Piedra de Luna

Supongo que podría agregar "" hasta el final de la cadena antes de analizar. - Piedra de Luna

Este planteamiento de « 10 400,"a1 b2",500 se convertirá 10 400,"alb2" - Piedra de Luna

Es posible que deba contar el número de cotizaciones para saber si las cotizaciones están equilibradas. podrías usar StringUtils.countMatches(input, "\"") or Pattern.compile("\\\"").matcher(input).groupCount(). Para la última cotización puedes usar input.lastIndexOf('"'). Considere tener referencias únicas de Pattern para evitar compilar la expresión regular cada vez. - Pablo Vargas

Aquí hay una pequeña rutina que parece funcionar bien cuando hay un solo conjunto de comillas en el texto:

public static String cropSpacesWithinQuotes(String expression) {
    Pattern pattern = Pattern.compile("\"[\\S*\\s\\S*]*\"");
    StringBuilder noSpaces=new StringBuilder();
    int initialPosition=0;
    Matcher matcher = pattern.matcher(expression);
    while (matcher.find(initialPosition)) {
            int pos=matcher.start();
            noSpaces.append(expression.substring(initialPosition, pos-initialPosition));
            initialPosition=matcher.end();
            noSpaces.append(matcher.group().replaceAll(" ", ""));
    }
    noSpaces.append(expression.substring(initialPosition));
    return(noSpaces.toString());
}

Al realizar algunas pruebas unitarias, me di cuenta de que cuando hay más de un par de comillas, el texto dentro de los dos conjuntos también tiene sus espacios recortados. Un poco de manipulación en la variable initialPosition debería resolver su problema.

Espero que esto ayude.

contestado el 22 de mayo de 12 a las 19:05

Sí, ese es uno de los problemas que estaba teniendo al tratar de convertir esto en una expresión regular de una línea. - Piedra de Luna

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.