paola91
paola91

Reputation: 369

Matching regular expressions in Android

I want to extract specific information from a string like this:

String content = "ObjectValue(Name1) ObjectValue(Name2) ObjectValue(Name3)";

I want to use regular expressions in order to extract only:

Name1 Name2 Name3

But I can't succeed. Here's my code:

private static final String OBJECT_VALUE = "ObjectValue";
String content = "ObjectValue(Name1) ObjectValue(Name2) ObjectValue(Name3)";
String patternString = OBJECT_VALUE+"\\((.+)\\)";
Pattern pattern = Pattern.compile(patternString);
Matcher matcher = pattern.matcher(content);
    
if(matcher.find()) {
        for (int i = 0; i < matcher.groupCount(); i++) {
            Log.d("Found items", matcher.group(i));
        }
        
    }

Here's the output:

Found items: ObjectValue(Name1) ObjectValue(Name2) ObjectValue(Name3)

So, first of all, I want to extract only the names, and I clearly missing something in the regex. Secondly, I want distinct elements of the group, while in the output, the group consist of a single element, is it possible?

Upvotes: 1

Views: 38

Answers (2)

Ben P.
Ben P.

Reputation: 54204

To elaborate on Wiktor's answer, there are two problems here.

The first is that, for the input string "ObjectValue(Name1) ObjectValue(Name2) ObjectValue(Name3)" and the pattern ObjectValue\((.+)\), the .+ can match "Name1) ObjectValue(Name2) ObjectValue(Name3".

The second is that matcher.group(0) behaves a little strangely. From the documentation:

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

Upvotes: 1

Wiktor Stribiżew
Wiktor Stribiżew

Reputation: 626893

You need to use a non-greedy regex and use while to grab only Group 1 value:

String content = "ObjectValue(Name1) ObjectValue(Name2) ObjectValue(Name3)";
String patternString = OBJECT_VALUE+"\\(([^()]+)\\)";
Pattern pattern = Pattern.compile(patternString);
Matcher matcher = pattern.matcher(content);
while(matcher.find()) {
    Log.d("Found item:", matcher.group(1));
}

See this Java demo

Patter details:

  • \\( - a literal (
  • ([^()]+) - Group 1 matching 1+ chars other than ( and ) (the one that is accessed with matcher.group(1))
  • \\) - a literal )

Note that if turned into while, and there is no need to loop over matcher.groupCount() since we know that the required value is in Group 1.

Upvotes: 1

Related Questions