2012-05-23 13 views
6

Estoy buscando una forma de simplificar una expresión regular que consta de valores (por ejemplo, 12345), signos de relación (<,>, < =,> =) y juntores (&,!). P.ej. la expresión:Simplifica una expresión regular compleja

>= 12345 & <=99999 & !55555 

debe coincidir. Tengo esta expresión regular:

(^<=|^<= | ^>= | ^>= |^<|^>|^< |^> |^)((!|)([0-9]{1,5}))(& > | & < |& >=|&>=|&<=||&<=|&>=|&<|&>|&| &| & |$))* 

Estoy especialmente satisfecho con la repetición de < =,> =, <,> al principio y al final de la expresión. Estaría encantado de obtener una pista sobre cómo hacerlo más simple, por ej. mira hacia adelante, mira atrás.

+0

¿cuál quieres que sea el resultado? –

+0

Por favor, muestre algunas coincidencias y resultados, y tal vez algunos ejemplos de no coincidencias. Esto nos ayudará a entender lo que estás buscando hacer. – kevlar1818

+0

Si una expresión puede tener una longitud arbitraria, entonces quizás desee hacer algo un poco más práctico que las expresiones regulares, de lo contrario se pondrá bastante feo y difícil de leer. – kevin628

Respuesta

0

Puede hacer que todos los espacios sean opcionales (con signos de interrogación) para que no tenga que enumerar explícitamente todas las posibilidades. También puede agrupar los símbolos de igualdad/desigualdad en un juego de caracteres ([]).

como no, creo que

(^[<>]=?\s?)((!|)([0-9]{1,5}))(\s?&\s?[<>]=?\s|$)* 
+0

Esto coincidirá con '=', sin mencionar '> = <', '>>', '==>', etc. – kevlar1818

+0

@ kevlar1818: Correcto, pero ¿es probable que ocurran? [<>] =? de hecho es mejor, editado. – Junuxx

+0

Negar la aparición de patrones (aunque el patrón es improbable) no es una buena etiqueta de expresiones regulares. – kevlar1818

0

¿Qué tal

[<>]=?|\d{1,5}|[&!\|]

que se encarga de su> /> =/</< = repetición. Parece funcionar para mi.

Avísame si esto responde a tu pregunta o si necesita trabajo.

+0

Nice one @ kevlar1818. Pero ¿no captará también "> = <= 12345 & <= 99999 &! 55555". ¿Queremos que capte ese tipo de ejemplos? – Zecas

+0

Propongo mejorar tu respuesta con '(([<>] =? |!) \ S * \ d {1,5} \ s *) (& \ s + ([<>] =? |!) \ S * \ d {1,5} \ s *) * '. ¿Qué piensas @ kevlar1818? – Zecas

0

Tengo un procedimiento de dos pasos en mente. Primero rompa por junctor, luego verifique las partes individuales.

final String expr = ">= 12345 & <=99999 & !55555".replaceAll("\\s+", ""); 
for (String s : expr.split("[|&]")) 
    if (!s.matches("([<>]=?|=|!)?\\d+")) { System.out.println("Invalid"); return; } 
System.out.println("Valid"); 

Pero todavía nos quedan dudas si se trata de validación o alguna otra cosa.

0

parece que está haciendo un gran esfuerzo para encontrar espacios opcionales. algo así como \s? (0 - 1) o \s* (0 - muchos) sería mejor.

también, los elementos repetidos separados por algo siempre son difíciles. es mejor hacer una expresión regular para la "cosa" para simplificar la repetición.

limit = '\s*([<>]=?|!)\s*\d{1,5}\s*' 
one_or_more = '^' + limit + '(&' + limit + ')*$' 

o, amplió a cabo:

^\s*([<>]=?|!)\s*\d{1,5}\s*(&\s*([<>]=?|!)\s*\d{1,5}\s*)*$ 

también, ! es una "señal de relación" y no un "juntor" si yo estoy entendiendo correctamente.

(para las personas que abogan por el uso de un programa de análisis "real", lo anterior - la estructura de one_or_more - es probablemente la forma en que terminaría la aplicación de la & lista Separado, no hay necesidad de un analizador si sólo se puede utilizar cuerdas concatenación en el lenguaje).

0

Esto es lo que quiere:

^(\s*([<>]=?)?\s*!?\d{1,5}\s*(&|$))* 

Estas explicaciones de sub expresiones suma deben ayudar a entender todo el asunto:

\s*: 0 o más espacios
([<>]=?)?: Un < o > signo seguido opcionalmente por un =, todo opcional
!?: Y opcional !
\d{1,5}: 1-5 dígitos
(&|$): Cualquiera de una & o al final de la cadena

1

A partir de su expresión regular, usted puede hacer esto de simplificación pasos:

(^<=|^<= | ^>= | ^>= |^<|^>|^< |^> |^)((!|)([0-9]{1,5}))(& > | & < |& >=|&>=|&<=||&<=|&>=|&<|&>|&| &| & |$))* 
  1. Mueva el ancla de la alternancia

    ^(<=|<= |>= |>= |<|>|< |> |)((!|)([0-9]{1,5}))(& > | & < |& >=|&>=|&<=||&<=|&>=|&<|&>|&| &| & |$))* 
    

    ¿Por qué ha habido? Has espacios en blanco antes del ancla? (Eliminado eso)

  2. mueva los siguientes espacios en blanco exterior y hacen que sea opcional

    ^(<=|<=|>=|>=|<|>|<|>|) ?((!|)([0-9]{1,5}))(& > | & < |& >=|&>=|&<=||&<=|&>=|&<|&>|&| &| & |$))* 
    
  3. eliminar los duplicados en el alternancias

    ^(<=|>=|<|>|) ?((!|)([0-9]{1,5}))(& > | & < |& >=|&>=|&<=||&<=|&>=|&<|&>|&| &| & |$))* 
    
  4. La alternativa vacía al final se correspondería con el vacío cadena ==> esta alternancia es opcional

    ^((<=|>=|<|>)? ?)?((!|)([0-9]{1,5}))(& > | & < |& >=|&>=|&<=||&<=|&>=|&<|&>|&| &| & |$))* 
    
  5. Hacer el signo igual opcional y eliminar los duplicados

    ^((<|>)=? ?)?((!|)([0-9]{1,5}))(& > | & < |& >=|&>=|&<=||&<=|&>=|&<|&>|&| &| & |$))* 
    
  6. La alternancia con los caracteres individuales se puede sustituir por una clase de caracteres

    ^([<>]=? ?)?((!|)([0-9]{1,5}))(& > | & < |& >=|&>=|&<=||&<=|&>=|&<|&>|&| &| & |$))* 
    
  7. hacer cosas similares con la alternancia en el extremo y usted terminar con algo como esto:

    ^([<>]=? ?)?((!|)([0-9]{1,5}))(?(& ?([<>]=?)?)?|$) 
    

Esto no se ha probado, no cambié la semántica (creo), pero lo hice aquí en el editor.

Cuestiones relacionadas