2012-06-20 20 views
26

Estoy tratando de crear dos expresiones regulares que coincidan con los URI. Estos URI tienen el formato: /foo/someVariableData y /foo/someVariableData/bar/someOtherVariableDataJava regex: Negative lookahead

Necesito dos expresiones regulares. Cada uno tiene que coincidir con uno pero no con el otro.

Las expresiones geográficas que originalmente se me ocurrió son: /foo/.+ y /foo/.+/bar/.+ respectivamente.

Creo que la segunda expresión regular está bien. Solo coincidirá con la segunda cadena. La primera expresión regular, sin embargo, coincide con ambos. Entonces, comencé a jugar (por primera vez) con un lookaid negativo. Diseñé la expresión regular /foo/.+(?!bar) y configurar el código siguiente para probar que

public static void main(String[] args) { 
    String shouldWork = "/foo/abc123doremi"; 
    String shouldntWork = "/foo/abc123doremi/bar/def456fasola"; 
    String regex = "/foo/.+(?!bar)"; 
    System.out.println("ShouldWork: " + shouldWork.matches(regex)); 
    System.out.println("ShouldntWork: " + shouldntWork.matches(regex)); 
} 

Y, por supuesto, ambos a resolver true.

¿Alguien sabe lo que estoy haciendo mal? No necesito usar Negative lookahead necesariamente, solo necesito resolver el problema, y ​​creo que un lookahead negativo podría ser una forma de hacerlo.

Gracias,

Respuesta

51

intenta

String regex = "/foo/(?!.*bar).+"; 

o posiblemente

String regex = "/foo/(?!.*\\bbar\\b).+"; 

para evitar fallos en los caminos como /foo/baz/crowbars que supongo que usted quiere que la expresión regular para que coincida.

Explicación: (sin las dobles barras invertidas requeridas por las cadenas de Java)

/foo/ # Match "/foo/" 
(?! # Assert that it's impossible to match the following regex here: 
.* # any number of characters 
\b # followed by a word boundary 
bar # followed by "bar" 
\b # followed by a word boundary. 
)  # End of lookahead assertion 
.+ # Match one or more characters 

\b, el "límite de palabra de anclaje", coincide con el espacio vacío entre un carácter alfanumérico y un carácter no alfanumérico (o entre el inicio/final de la cadena y un carácter alnum). Por lo tanto, coincide antes del b o después del r en "bar", pero no coincide entre w y b en "crowbar".

Protip: Eche un vistazo a http://www.regular-expressions.info - un excelente tutorial de expresiones regulares.