2008-09-04 15 views
16

Estoy buscando una expresión regular que coincida con una cadena que comienza con una subcadena y no termina con una cierta subcadena.Regex para que coincida con algo que no sea una subcadena específica

Ejemplo:

// Updated to be correct, thanks @Apocalisp 
^foo.*(?<!bar)$ 

debe coincidir con cualquier cosa que empieza con "foo" y no termina con "barra". Sé sobre la sintaxis [^ ...], pero no puedo encontrar nada que haga eso para una cadena en lugar de caracteres individuales.

Estoy específicamente tratando de hacer esto para la expresión regular de Java, pero me he encontrado con esto antes, por lo que las respuestas para otros motores de expresiones regulares también serían geniales.

Gracias a @Kibbee por verificar que esto también funciona en C#.

+0

Como he mencionado a continuación - expresión regular que se trate de cadena de entrada "foo123bar" que coincidirá "foo12" - espero que este sea el comportamiento deseado. – Dmitry

Respuesta

9

Creo que en este caso desea negativo de búsqueda hacia atrás, así:

foo.*(?<!bar) 
1

No estoy familiarizado con Java regex, pero la documentación para Pattern Class sugeriría que podría usar (?! X) para un lookahead negativo de ancho cero sin capturar (busca algo que no sea X en esa postisión, sin capturarlo como retroreferencia). Por lo que podría hacer:

foo.*(?!bar) // not correct 

actualización: el derecho de Apocalisp, que desea de búsqueda hacia atrás negativo. (está comprobando que las coincidencias. * no terminan con la barra)

+0

El problema con esta solución está en el hecho de que para la cadena de entrada "foo123bar" coincidirá con "foo12" - espero que este sea el comportamiento deseado. – Dmitry

0

Como dijeron otros comentaristas, necesita una mirada negativa hacia adelante. En Java se puede utilizar este patrón:

"^first_string(?!.?second_string)\\z" 
  • ^- asegura que la cadena se inicia con first_string
  • \ z - asegura que la cadena termina con second_string
  • - medios (second_string?!.?) first_string que no puede ser seguido por second_string
1
respuesta

verificado @ de Apocalisp usando:

import java.util.regex.Pattern; 
public class Test { 
    public static void main(String[] args) { 
    Pattern p = Pattern.compile("^foo.*(?<!bar)$"); 
    System.out.println(p.matcher("foobar").matches()); 
    System.out.println(p.matcher("fooBLAHbar").matches()); 
    System.out.println(p.matcher("1foo").matches()); 
    System.out.println(p.matcher("fooBLAH-ar").matches()); 
    System.out.println(p.matcher("foo").matches()); 
    System.out.println(p.matcher("foobaz").matches()); 
    } 
} 

Esta salida de las respuestas correctas:

false 
false 
false 
true 
true 
true 
Cuestiones relacionadas