tags:

views:

101

answers:

5

I'm trying to match the username with a regex. Please don't suggest a split.

USERNAME=geo

Here's my code:

    String input = "USERNAME=geo";
    Pattern pat = Pattern.compile("USERNAME=(\\w+)");
    Matcher mat = pat.matcher(input);
    if(mat.find()) {
        System.out.println(mat.group());
    }

why doesn't it find geo in the group? I noticed that if I use the .group(1), it finds the username. However the group method contains USERNAME=geo. Why?

+5  A: 

Because group() is equivalent to group(0), and group 0 denotes the entire pattern.

From the documentation:

public String group(int group)

Group zero denotes the entire pattern, so the expression m.group(0) is equivalent to m.group()

As you've found out, with your pattern, group(1) gives you what you want.

If you insist on using group(), you'd have to modify the pattern to something like "(?<=USERNAME=)\\w+".

polygenelubricants
`group()` does not always return whole string.
incarnate
I meant to say "entire pattern". Corrected.
polygenelubricants
Indeed, as per the `Matcher` javadoc: http://java.sun.com/javase/6/docs/api/java/util/regex/Pattern.html#cg *Group zero always stands for the entire expression.*
BalusC
Nope, that's *previous*, not entire. You may try following: `Matcher m = Pattern.compile("a\\w").matcher("abacad"); while (m.find()) System.out.println(m.group()); ` -- it should print following lines: `ab ac ad`
incarnate
BTW, cool pattern proposal for not to capture "USERNAME=" -- very clever (but a bit unreadable though).
incarnate
+3  A: 

As Matcher.group() javadoc says, it "returns the input subsequence matched by the previous match", and the previous match in your case was "USERNAME=geo" since you've called find().

In contrast, the method group(int) returns specific group. Capturing groups are numbered by counting their opening parentheses from left to right, so the first group would match "geo" in your case.

incarnate
+1  A: 

That's because group is supposed to return the string matching the pattern in its entirety. For getting a group within that string, you need to pass the group number that you want.

See here for details, paraphrased below:

group

public String group()
Returns the input subsequence matched by the previous match.

public String group(int group)
Returns the input subsequence captured by the given group during the previous match operation.
Capturing groups are indexed from left to right, starting at one. Group zero denotes the entire pattern, so the expression m.group(0) is equivalent to m.group().

paxdiablo
+1  A: 

So the VAR.group( int i ) will return the ith capture group of the regex. With 0 being the full string. You need to call .group( 1 )

Mimisbrunnr
Although your answer is fine, in the future you may want to elaborate a little more like the other respondents. "It's better to teach a man to fish etc..."
NomeN
+1  A: 

For your solution, here's what works:

public static void main(String[] args) {
        String input = "USERNAME=geo";
        Pattern pat = Pattern.compile("USERNAME=(\\w+)");
        Matcher mat = pat.matcher(input);
        if(mat.find()) {
            System.out.println(mat.group(1));
        }
    }

Output geo

Reason

String java.util.regex.Matcher.group(int group)
Returns the input subsequence captured by the given group during the previous match operation.

For a matcher m, input sequence s, and group index g, the expressions m.group(g) and s.substring(m.start(g), m.end(g)) are equivalent.

The Elite Gentleman