0

I would like to find the content of all the outer square brackets pairs in a string.

If an outer pair has an inner pair then it should not be matched separately.

For example string: [abc][123][cde[456[aq[]1q1]]] results should be:

  • abc
  • 123
  • cde[456[aq[]1q1]]

Any help will be highly appreciated...

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
  • You can't with java regex since it doesn't support recursion nor balancing groups. – Casimir et Hippolyte Nov 24 '14 at 15:42
  • You can't with **any** regex, since they [cannot match recursively by design](http://stackoverflow.com/questions/133601/can-regular-expressions-be-used-to-match-nested-patterns). – Andrzej Doyle Nov 24 '14 at 16:11
  • is there a limit to the levels of nesting? – alpha bravo Nov 24 '14 at 16:14
  • @AndrzejDoyle: We are not speaking about "regex" in a theorical meaning, but about the tool commonly called "regex" that is available in most language. A lot of these tools have a recursion feature (Perl, PHP, Ruby, libboost, the new Python regex module...) or a balancing groups feature like the .net framework. – Casimir et Hippolyte Nov 24 '14 at 16:33

3 Answers3

1

As already said, this is not possible with regex. Following is the way

public List<String> readValidJsonStrings(String allText) {   
    List<String> jsonList = new ArrayList<String>();
    int[] endsAt = new int[1];
    endsAt[0] = 0;
    while(true) {
        int startsAt = allText.indexOf("{", endsAt[0]);
        if (startsAt == -1) {
            break;
        }
        String aJson = parseJson(allText, startsAt, endsAt);
        jsonList.add(aJson);
    }
}

private static String parseJson(String str, int startsAt, int[] endsAt) {

    Stack<Integer> opStack = new Stack<Integer>();
    int i = startsAt + 1;
    while (i < str.length()) {

        if (str.charAt(i) == '}') {
            if (opStack.isEmpty()) {
                endsAt[0] = i + 1;
                return str.substring(startsAt, i + 1);
            } else {
                opStack.pop();
            }
        }else if (str.charAt(i) == '{') {
            opStack.push(i);
        }

        i++;
    }

    return null;
}

Change "{" to "[", and other fixes.

Nilesh
  • 2,089
  • 3
  • 29
  • 53
0

This works :)

      String[] ans=input.replaceAll("^\\[|\\]$","").replaceAll("\\]\\["," ").replaceAll("  ","\\[\\]\\[\\]").replaceAll("\\[\\] ","\\[\\]\\[\\]").split(" ");
      System.out.println(Arrays.toString(ans));
Prabhu R.D
  • 55
  • 7
-1
 "(^|\])\[(.*)\]($|[)"

using the most outer brackets always have a bracket next to them or end of string or start of string so this is essentially matching "[something]" if it's preceded by ^ or ] and has [ or $ after it.

Attila Neparáczki
  • 466
  • 1
  • 6
  • 14