Confused about Matcher group in Java regex
I have the following line,
typeName="ABC:xxxxx;";
I need to fetch the word ABC
,
I wrote the following code snippet,
Pattern pattern4=Pattern.compile("(.*):");
matcher=pattern4.matcher(typeName);
String nameStr="";
if(matcher.find())
{
nameStr=matcher.group(1);
}
So if I put group(0)
I get ABC:
but if I put group(1)
it is ABC
, so I want to know
What does this 0
and 1
mean? It will be better if anyone can explain me with good examples.
The regex pattern contains a :
in it, so why group(1)
result omits that? Does group 1 detects all the words inside the parenthesis?
So, if I put two more parenthesis such as, s*(d*)(.*)
: then, will be there two groups? group(1)
will return the (d*)
part and group(2)
return the (.*)
part?
The code snippet was given in a purpose to clear my confusions. It is not the code I am dealing with. The code given above can be done with String.split()
in a much easier way.
Capturing and grouping
Capturing group (pattern)
creates a group that has capturing property.
A related one that you might often see (and use) is (?:pattern)
, which creates a group without capturing property, hence named non-capturing group.
A group is usually used when you need to repeat a sequence of patterns, eg (.w+)+
, or to specify where alternation should take effect, eg ^(0*1|1*0)$
( ^
, then 0*1
or 1*0
, then $
) versus ^0*1|1*0$
( ^0*1
or 1*0$
).
A capturing group, apart from grouping, will also record the text matched by the pattern inside the capturing group (pattern)
. Using your example, (.*):
, .*
matches ABC
and :
matches :
, and since .*
is inside capturing group (.*)
, the text ABC
is recorded for the capturing group 1.
Group number
The whole pattern is defined to be group number 0.
Any capturing group in the pattern start indexing from 1. The indices are defined by the order of the opening parentheses of the capturing groups . As an example, here are all 5 capturing groups in the below pattern:
(group)(?:non-capturing-group)(g(?:ro|u)p( (nested)inside)(another)group)(?=assertion)
| | | | | | || | |
1-----1 | | 4------4 |5-------5 |
| 3---------------3 |
2-----------------------------------------2
The group numbers are used in back-reference n
in pattern and $n
in replacement string.
In other regex flavors (PCRE, Perl), they can also be used in sub-routine calls.
You can access the text matched by certain group with Matcher.group(int group)
. The group numbers can be identified with the rule stated above.
In some regex flavors (PCRE, Perl), there is a branch reset feature which allows you to use the same number for capturing groups in different branches of alternation .
Group name
From Java 7, you can define a named capturing group (?<name>pattern)
, and you can access the content matched with Matcher.group(String name)
. The regex is longer, but the code is more meaningful, since it indicates what you are trying to match or extract with the regex.
The group names are used in back-reference k<name>
in pattern and ${name}
in replacement string.
Named capturing groups are still numbered with the same numbering scheme, so they can also be accessed via Matcher.group(int group)
.
Internally, Java's implementation just maps from the name to the group number. Therefore, you cannot use the same name for 2 different capturing groups.
For The Rest Of Us
Here is a simple and clear example of how this works
Regex: ([a-zA-Z0-9]+)([s]+)([a-zA-Z ]+)([s]+)([0-9]+)
String: "!* UserName10 John Smith 01123 *!"
group(0): UserName10 John Smith 01123
group(1): UserName10
group(2):
group(3): John Smith
group(4):
group(5): 01123
As you can see, I have created FIVE groups which are each enclosed in parentheses.
I included the !* and *! on either side to make it clearer. Note that none of those characters are in the RegEx and therefore will not be produced in the results. Group(0) merely gives you the entire matched string (all of my search criteria in one single line). Group 1 stops right before the first space because the space character was not included in the search criteria. Groups 2 and 4 are simply the white space, which in this case is literally a space character, but could also be a tab or a line feed etc. Group 3 includes the space because I put it in the search criteria ... etc.
Hope this makes sense.
Parenthesis ()
are used to enable grouping of regex phrases.
The group(1)
contains the string that is between parenthesis (.*)
so .*
in this case
And group(0)
contains whole matched string.
If you would have more groups (read (...)
) it would be put into groups with next indexes (2, 3 and so on).
上一篇: 正则表达式:不是任意的非捕获组