0

I think what I am asking is either very trivial or already asked, but I have had a hard time finding answers.

We need to capture the inner number characters between brackets within a given string.

so given the string

StringWithMultiArrayAccess[0][9][4][45][1]

and the regex

^\w*?(\[(\d+)\])+?

I would expect 6 capture groups and access to the inner data. However, I end up only capturing the last "1" character in capture group 2.

If it is important heres my java junit test:

@Test
public void ensureThatJsonHandlerCanHandleNestedArrays(){
    String stringWithArr = "StringWithMultiArray[0][0][4][45][1]";
    Pattern pattern = Pattern.compile("^\\w*?(\\[(\\d+)\\])+?");


    Matcher matcher = pattern.matcher(stringWithArr);
    matcher.find();

    assertTrue(matcher.matches()); //passes

    System.out.println(matcher.group(2));  //prints 1 (matched from last array symbols)

    assertEquals("0", matcher.group(2)); //expected but its 1 not zero
    assertEquals("45", matcher.group(5));  //only 2 capture groups exist, the whole string and the 1 from the last array brackets

}
AnthonyJClink
  • 1,008
  • 2
  • 11
  • 32
  • Is the string before the numbers really important? When you repeat a capture group, only the last capture will remain in the captured group. – Jerry Mar 29 '14 at 11:51

1 Answers1

1

In order to capture each number, you need to change your regex so it (a) captures a single number and (b) is not anchored to--and therefore limited by--any other part of the string ("^\w*?" anchors it to the start of the string). Then you can loop through them:

Matcher mtchr = Pattern.compile("\\[(\\d+)\\]").matcher(arrayAsStr);
while(mtchr.find())  {
   System.out.print(mtchr.group(1) + " ");
}

Output:

0 9 4 45 1
aliteralmind
  • 19,847
  • 17
  • 77
  • 108
  • Before I accept your answer, which is correct and does work... I was wondering how I could ensure that theres no space between the word and the first bracket, and the space between the last bracket and the end of the line... thats not really important... but would add extreme value in my scenario. BTW, the looping was extremely valuable. – AnthonyJClink Mar 29 '14 at 13:10
  • 1
    First match the line as a whole with "^\\w+(?:\\\[(\\d+)\\\])+$". When this is found (when "mtchr.matches()" is true) run the above as in my answer. – aliteralmind Mar 29 '14 at 14:20