Regex no funciona en Android pero funciona bien en Java
Tengo el siguiente código:
String compact = Pattern.compile(" *(\\{) *| *(\\}) *").matcher(" { { } } ") .replaceAll("$1$2");
En Java, compact
contiene {{}}
– que es lo que quiero – pero en Android, estoy recibiendo {null{nullnull}null}
que me está volviendo loco. ¿Estoy haciendo algo mal?
- ¿Cómo validar una cadena usando java regex?
- Detectar subrogados altos en una cadena utilizando expresiones regulares
- "Secuencia de escape no válida (válidos son \ b \ t \ n \ f \ r \" \ '\\) "error de sintaxis
- ¿Cómo puedo eliminar el "+" y el código del país de un número de teléfono?
- ¿Puedo hacer regex reemplazar en Android con grupos del partido?
La siguiente línea produce el mismo resultado en Android:
String compact = " { { } } ".replaceAll(" *(\\{) *| *(\\}) *", "$1$2")
Aquí está una versión en línea de Java para cualquier persona que quiera jugar con ella.
Si ayuda, estoy compilando contra Android SDK 23 con jdk1.7.0_79 en Mac en Android Studio.
Actualización: El uso de "\\s*(\\{)\\s*|\\s*(\\})\\s*"
tiene el mismo efecto.
- Android: ¿dividido en un salto de línea en String? (Párrafos)
- Expresión regular de Android para obtener enlaces de la fuente de la página web
- ¿Cuál sería una simple expresión regular para la comprobación de contraseña durante la suscripción?
- Android java regex coinciden con todos menos un carácter
- Cómo utilizar la expresión regular en android
- División de una cadena en Java lanza PatternSyntaxException
- Palabra árabe Buscando en el archivo de texto en árabe
- Fuerza de cierre en la expresión regular!
No puedo decirte por qué se comporta así en Java, pero puedo decirte por qué se comporta así en Android. Puedo dar algunas pistas sobre Java sin embargo.
Cuando Matcher#replaceAll(String)
un Matcher#replaceAll(String)
, la clase comprueba si hay un find()
, y si lo tiene, reemplaza lo que se emparejó en la entrada con esa String
reemplazo que proporcionaste.
Hasta aquí todo bien.
Sin embargo, cuando el reemplazo es realmente una representación de un grupo, se toma otra ruta. La clase intenta encontrar lo que corresponde a ese grupo (vea Matcher#appendEvaluated(StringBuffer, String)
) y append(String)
al StringBuffer
interno que se usa internamente.
Lo hace llamando explícitamente al método group(int)
. El comportamiento de este método tanto en Java como en Android es que devolverá null
si, cuando hay una coincidencia, no hay una que corresponda al grupo dado. Nota: lanza la excepción cuando no hay un fósforo en absoluto y no sólo cuando no puede encontrar uno que corresponde al grupo. Como el group(int)
sin find()
, por ejemplo.
Al final, StringBuffer
emite la String
"null" (literalmente la palabra "null") cuando se agrega un objeto null
. Por lo tanto, para cada grupo que usted pide que no esté allí, cuando hay un fósforo, agregará la palabra "null" a ella.
Los algoritmos utilizados en Java son muy diferentes y tienen una salida diferente en ese caso de replaceAll
.
Sin probar demasiado o la fijación de ineficiencias (lo siento, sólo navegar SO a las 3 de la mañana en diciembre no me ayuda a pensar en línea recta), creo que podría lograr, en Android, los mismos resultados que obtendría utilizando lo que estaba utilizando en Java, haciendo esto en lugar de replaceAll
:
String input = " { { } } "; Matcher matcher = Pattern.compile(" *(\\{) *| *(\\}) *").matcher(input); while (matcher.find()) { String a = matcher.group(1); // $1 String b = matcher.group(2); // $2 String replacement = null; if (a != null && b != null) { replacement = a + b; } else if (a != null) { replacement = a; } else if (b != null) { replacement = b; } if (replacement != null) { input = input.replace(matcher.group(), replacement); } }
Si no lo hace, por favor hágamelo saber. Sólo hice algunas pruebas de crudo (es 3 am después de todo).
- Cómo mostrar el estado de la conexión bluetooth en android
- Mover EditText en NestedScrollView cuando aparece el teclado virtual