2013-08-02 17 views
15

Ho il seguente codice Java:Java RegEx lookbehind negativo

Pattern pat = Pattern.compile("(?<!function)\\w+"); 
Matcher mat = pat.matcher("function example"); 
System.out.println(mat.find()); 

Perché mat.find() ritorno vero? Ho usato lookbehind negativo e example è preceduto da function. Non dovrebbe essere scartato?

risposta

29

vedere che cosa corrisponde:

public static void main(String[] args) throws Exception { 
    Pattern pat = Pattern.compile("(?<!function)\\w+"); 
    Matcher mat = pat.matcher("function example"); 
    while (mat.find()) { 
     System.out.println(mat.group()); 
    } 
} 

uscita:

function 
xample 

Quindi, prima si trova function, che non è preceduto da "function". Quindi trova xample preceduto da function e e quindi non "function".

Presumibilmente si desidera che il modello per abbinare il testo tutta, non solo trovare le corrispondenze nel testo.

È possibile fare questo con Matcher.matches() o è possibile modificare il modello per aggiungere inizio e di fine ancoraggi:

^(?<!function)\\w+$ 

Io preferisco il secondo approccio in quanto significa che il modello si definisce la sua regione partita piuttosto che la regione definita dal suo utilizzo. Questa è solo una questione di preferenza comunque.

1

La stringa contiene la parola "funzione" che corrisponde a \ w + e non è preceduta da "funzione".

0

notare due cose qui:

  • Stai usando find() che restituisce vero per un sub-string partita così.

  • A causa di quanto sopra, "funzione" corrisponde poiché non è preceduta da "funzione".
    L'intera stringa non avrebbe mai dovuto corrispondere perché l'espressione regolare non include spazi inclusi.

Uso Mathcher#matches() o ^ e $ tasselli con lookahead negativo invece:

Pattern pat = Pattern.compile("^(?!function)[\\w\\s]+$"); // added \s for whitespaces 
Matcher mat = pat.matcher("function example"); 

System.out.println(mat.find()); // false