Java RegEx negative lookbehind

Sorin picture Sorin · Aug 2, 2013 · Viewed 20.2k times · Source

I have the following Java code:

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

Why does mat.find() return true? I used negative lookbehind and example is preceded by function. Shouldn't it be discarded?

Answer

Boris the Spider picture Boris the Spider · Aug 2, 2013

See what it matches:

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

Output:

function
xample

So first it finds function, which isn't preceded by "function". Then it finds xample which is preceded by function e and therefore not "function".

Presumably you want the pattern to match the whole text, not just find matches in the text.

You can either do this with Matcher.matches() or you can change the pattern to add start and end anchors:

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

I prefer the second approach as it means that the pattern itself defines its match region rather then the region being defined by its usage. That's just a matter of preference however.