sheet online matches cheat java regex

online - ¿Cómo puedo realizar una coincidencia parcial con java.util.regex.*?



regex java 8 (7)

He estado usando las clases java.util.regex. * Para expresiones regulares en Java y todas buenas hasta el momento. Pero hoy tengo un requisito diferente. Por ejemplo, considere el patrón como "aabb". Ahora, si la cadena de entrada es aa, definitivamente no coincidirá, sin embargo, todavía existe la posibilidad de que si agrego bb se convierta en aabb y coincida. Sin embargo, si hubiera comenzado con cc, no importa lo que agregue, nunca coincidirá.

He explorado la clase de Patrón y Matcher, pero no encontré ninguna forma de lograr esto.

La entrada provendrá del usuario y el sistema tendrá que esperar hasta que el patrón coincida o nunca volverá a coincidir independientemente de cualquier entrada adicional.

¿Cualquier pista?

Gracias.


Deberías haber examinado más de cerca la API Matcher; El método hitEnd() funciona exactamente como lo describiste:

import java.util.regex.*; public class Test { public static void main(String[] args) throws Exception { String[] ss = { "aabb", "aa", "cc", "aac" }; Pattern p = Pattern.compile("aabb"); Matcher m = p.matcher(""); for (String s : ss) { m.reset(s); if (m.matches()) { System.out.printf("%-4s : match%n", s); } else if (m.hitEnd()) { System.out.printf("%-4s : partial match%n", s); } else { System.out.printf("%-4s : no match%n", s); } } } }

salida:

aabb : match aa : partial match cc : no match aac : no match

Que yo sepa, Java es el único lenguaje que expone esta funcionalidad. También está el método requireEnd() , que le dice si más información podría convertir una coincidencia en una no coincidencia, pero no creo que sea relevante en su caso.

Ambos métodos se agregaron para admitir la clase Scanner, por lo que puede aplicar expresiones regulares a un flujo sin necesidad de que todo el flujo se lea en la memoria.


Entonces, ¿no quiere saber si una Cadena s coincide con la expresión regular, sino si podría haber una Cadena más larga que comience con s? Lo sentimos, Regexes no puede ayudarte allí porque no tienes acceso al estado interno del emparejador; solo obtienes el resultado booleano y cualquier grupo que hayas definido, por lo que nunca sabes por qué falló una coincidencia.

Si está dispuesto a hackear las bibliotecas JDK, puede ampliar (o probablemente bifurcar) java.util.regex y proporcionar más información sobre el proceso de coincidencia. Si la coincidencia falló porque la entrada se "agotó", la respuesta sería verdadera ; si fallaba debido a la discriminación de carácter u otros controles, sería falso . Sin embargo, parece mucho trabajo, porque su problema es completamente opuesto a lo que se supone que deben hacer las expresiones regulares.

Otra opción: tal vez simplemente pueda redefinir la tarea para que pueda tratar la entrada como la expresión regular y hacer coincidir aabab con * aa. **? Sin embargo, debes tener cuidado con los metacaracteres de expresiones regulares.


Es posible que pueda lograr esto con una máquina de estado ( http://en.wikipedia.org/wiki/State_machine ). Haga que sus estados / transiciones representen una entrada válida y un estado de error. A continuación, puede alimentar a la máquina de estado un carácter (posiblemente, subcadena según sus datos) a la vez. En cualquier momento, puede verificar si su máquina de estado está en estado de error. Si no está en el estado de error, entonces sabe que la entrada futura aún puede coincidir. Si está en el estado de error, entonces sabe que algo falló anteriormente y cualquier entrada futura no hará que la cadena sea válida.


Para el ejemplo que da, podría intentar usar un antipatrón para descalificar resultados no válidos. Por ejemplo, "^ [^ a]" le diría que la entrada "c ..." no puede coincidir con su patrón de ejemplo de "aabb".

Dependiendo de su patrón, es posible que pueda dividirlo en patrones más pequeños para verificar y usar varios emparejadores y luego establecer sus límites a medida que se produce una coincidencia y se pasa a la siguiente. Este enfoque puede funcionar pero si su patrón es complejo y puede tener subpartes de longitud variable, puede terminar reimplementando parte del emparejador en su propio código para ajustar los límites posibles de la coincidencia para hacerlo más o menos codicioso. Una idea general de pseudocódigo de esto sería:

boolean match(String input, Matcher[] subpatterns, int matchStart, int matchEnd){ matcher = next matcher in list; int stop = matchend; while(true){ if matcher.matches input from matchstart -> matchend{ if match(input, subpatterns, end of current match, end of string){ return true; }else{ //make this match less greedy stop--; } }else{ //no match return false; } } }

Luego, puede combinar esta idea con los anti-patrones, y tener anti-sub-patrones y después de cada sub-patrón coinciden, verifique el siguiente anti-patrón, si coincide con usted sabe que ha fallado, de lo contrario continúe con el patrón correspondiente. Es probable que desee devolver algo como una enumeración en lugar de un valor booleano (es decir, ALL_MATCHED, PARTIAL_MATCH, ANTI_PATTERN_MATCH, ...)

Una vez más, dependiendo de la complejidad de su patrón real con el que está tratando de hacer coincidir la escritura de los sub patrones / antipatrón apropiados, puede ser difícil, si no imposible.


Si hace que cada carácter de la expresión regular sea opcional y relaje las restricciones de multiplicidad, obtendrá un poco lo que desea. Por ejemplo, si tiene un patrón coincidente "aa (abc) + bbbb", puede tener un patrón de "coincidencia posible" a? A? (A? B? C?) * B? B? B? B? ''.

Sin embargo, esta forma mecánica de producir un patrón de coincidencia posible no cubre construcciones avanzadas como las referencias hacia adelante y hacia atrás.


Una forma de hacer esto es analizar su expresión regular en una secuencia de subexpresiones, y luego volver a montarlos de una manera que le permita hacer coincidencias parciales; por ejemplo, "ab c" tiene 3 subexpresiones "a", "b " y "c" que luego puede volver a ensamblar como "a (b * (c)?)?".

Las cosas se complican cuando la expresión regular de entrada contiene alternancia y grupos, pero el mismo enfoque general debería funcionar.

El problema con este enfoque es que la expresión regular resultante es más complicada y podría llevar a un retroceso excesivo para las expresiones regulares de entrada complejas.


Pattern p = Pattern.compile(expr); Matcher m = p.matcher(string); m.find();