2012-06-20 15 views
26

Sto tentando di creare due espressioni regolari che corrisponderanno agli URI. Questi URI hanno il formato: /foo/someVariableData e /foo/someVariableData/bar/someOtherVariableDataEspressione regolare Java: lookahead negativo

Ho bisogno di due regex. Ognuno deve corrispondere uno ma non l'altro.

Le espressioni regolari che in origine si avvicinò con sono: /foo/.+ e /foo/.+/bar/.+ rispettivamente.

Penso che la seconda regex sia valida. Corrisponde solo alla seconda stringa. La prima espressione regolare, tuttavia, corrisponde a entrambi. Così, ho iniziato a giocare (per la prima volta) con un lookahead negativo. Ho progettato la regex /foo/.+(?!bar) e impostare il seguente codice di provarlo

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)); 
} 

E, naturalmente, entrambi a risolvere true.

Qualcuno sa cosa sto facendo male? Non ho bisogno di usare necessariamente il lookahead negativo, ho solo bisogno di risolvere il problema, e penso che il lookahead negativo potrebbe essere un modo per farlo.

Grazie,

risposta

51

provare

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

o forse

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

per evitare errori su percorsi come /foo/baz/crowbars che presumo si vuole che regex da abbinare.

Spiegazione: (senza i doppi backslash richiesti da stringhe 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, il "limite di parola di ancoraggio" partite lo spazio vuoto tra un carattere alfanumerico e di un carattere non alfanumerico (o tra l'inizio/fine della stringa e un carattere di alnum). Pertanto, corrisponde a o dopo il , ma non riesce a corrispondere tra w e b in "crowbar".

Protip: dai un'occhiata a http://www.regular-expressions.info - un ottimo tutorial sull'espressione regolare.

Problemi correlati