1

I am trying to extract the name of a property referenced in a string using the $() construct. For instance, if bb=xo-xo, then "aa$(bb)aa" expands to "aaxo-xoaa".

Here is the code:

public static void main(String[] args) {
  final String PROPERTY_NAME_REGEX = "\\w+(?:\\.\\w+)*";
  final String PROPERTY_REFERENCE_REGEX = "\\$\\((" + PROPERTY_NAME_REGEX + ")\\)";
  Pattern pattern = Pattern.compile(PROPERTY_REFERENCE_REGEX);
  String value = "hhh $(aa.bbcc.dd) @jj $(aakfd) j";
  Matcher matcher = pattern.matcher(value);
  StringBuffer sb = new StringBuffer();
  while (matcher.find()) {
    System.out.println(String.format("\"%s\" at [%d-%d)",
      matcher.group(),
      matcher.start(),
      matcher.end()));
    for (int i = 0; i < matcher.groupCount(); ++i) {
      System.out.println(String.format("group[%d] = %s", i, matcher.group(i)));
    }
  }
}

And it displays:

"$(aa.bbcc.dd)" at [4-17)
group[0] = $(aa.bbcc.dd)
"$(aakfd)" at [22-30)
group[0] = $(aakfd)

But I was hoping to get the following output:

"$(aa.bbcc.dd)" at [4-17)
group[0] = aa.bbcc.dd
"$(aakfd)" at [22-30)
group[0] = aakfd

What am I doing wrong?

5
  • 3
    "Some people, when confronted with a problem, think 'I know, I'll use regular expressions.' Now they have two problems." - Jamie Zawinski Commented Mar 4, 2012 at 19:08
  • "Beauty is in the eyes of the beholder". Commented Mar 4, 2012 at 19:10
  • take a look at the for loop. The groups index begin with 1 for the parenthesis enclosed matches Commented Mar 4, 2012 at 19:18
  • Sorry for being a smartass. You should use a parser for this, not regex.. You could take a look at the ExpandProperties class from ant, which does exactly this type of replacements. Commented Mar 4, 2012 at 19:22
  • Agreed. I have another question -stackoverflow.com/questions/9558411/… Commented Mar 4, 2012 at 20:14

2 Answers 2

2

To answer your specific problem, you should be looking at group[1], not group[0].

The Matcher.groupCount() method does not include group[0] in the count, thus your for loop is never showing you the group[1] matches because i < matcher.groupCount() is false.

Change your condition to i <= matcher.groupCount() and your output will be more enlightening.

That said, there are better ways of doing this than writing your own regex - e.g. http://api.dpml.net/ant/1.6.4/org/apache/tools/ant/filters/ExpandProperties.html

Sign up to request clarification or add additional context in comments.

1 Comment

Agreed. I have another question -stackoverflow.com/questions/9558411/…
0

Group 0 is always the entire match, regardless of any specified capturing groups. To top this off, Matcher.groupCount() returns the number of capturing groups, excluding the entire match. To get the result you were after, change your for loop to the following (notice that it starts at 1, and continues one step further due to the added equal sign):

for (int i = 1; i <= matcher.groupCount(); i++) {

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.