Home > other >  Get all text between bracket but skip nested bracket Java
Get all text between bracket but skip nested bracket Java

Time:08-24

I'm trying to get all text that is in brackets "test_two".

String test = "
    test_one{
     My Text One
    }
    test_two{
     My Text Two
       sub_test_one{
         My Sub Text
        }
       sub_test_two{
         My Sub Text
        }
    }
    test_three{
     My Text Three
    }"

My Code:

        int testOne = test.indexOf("test_two");
        int startTestOne = test.indexOf('{', testOne);
        int endTestOne = test.indexOf('}', testOne);
        String test3_2 = test.substring(startTestOne   2, endTestOne);

which gives me, but i want whole text from "test_two" brackets

My Text Two
       sub_test{
         My Sub Text

CodePudding user response:

Nesting means, that there's an opening brace before the closing brace. We can make use of this property to ignore all nested elements.

String test = """
    test_one{
     My Text One
    }
    test_two{
     My Text Two
       sub_test_one{
         My Sub Text
        }
       sub_test_two{
         My Sub Text
        }
    }
    test_three{
     My Text Three
    }""";

String testTwoLabel = "test_two";
int startOfTestTwoLabel = test.indexOf(testTwoLabel);
int startOfTestTwo = test.indexOf("{", startOfTestTwoLabel);

int nextClosingBrace = startOfTestTwo;
int nextOpeningBrace;
do {
    nextOpeningBrace = test.indexOf("{", nextClosingBrace);
    nextClosingBrace = test.indexOf("}", nextClosingBrace   1);
} while (nextOpeningBrace != -1 && nextOpeningBrace < nextClosingBrace);

String content = test.substring(startOfTestTwo   1, nextClosingBrace);

Update for multi-level-nesting:

String test = """
 test_one{ My Text One }
 test_two{ My Text Two 
   sub_test_one{ My Sub Text 
     sub_sub_test_one{ 
        My Sub Text 
          sub_sub_sub_test_one{ My Sub Text }
     } 
   }
   sub_test_two{ My Sub Text } 
} 
test_three{ My Text Three }""";

String testTwoLabel = "test_two";
int startOfTestTwoLabel = test.indexOf(testTwoLabel);
int startOfTestTwo = test.indexOf("{", startOfTestTwoLabel);
int closingBrace = -1;
int numOfOpenBraces = 1;
int pos = startOfTestTwo   1;
final int len = test.length();
while (pos < len && numOfOpenBraces > 0) {
    int ch = test.charAt(pos);
    switch (ch) {
        case '{': numOfOpenBraces  ; break;
        case '}': 
            numOfOpenBraces--;
            closingBrace = pos;
            break;
    }
    pos  ;
}
String content = test.substring(startOfTestTwo   1, closingBrace);

CodePudding user response:

To get the text between the curly brackets that start immediately after the target label (test_two) we can iterate over the given string and maintain StringBuilder, which would eventually contain the result, and a stack of brackets represented as a Deque.

When the brackets are balanced, i.e. the stack is empty, and we're not at the first opening curly after test_two, we're done.

String test = """
    test_one{
     My Text One
    }
    test_two{
     My Text Two
       sub_test_one{
         My Sub Text
        }
       sub_test_two{
         My Sub Text
        }
    }
    test_three{
     My Text Three
    }""";

int target = test.indexOf("test_two");
int firstOpeningCurly = test.indexOf('{', target);
        
StringBuilder testTwoText = new StringBuilder();
Deque<Character> brackets = new ArrayDeque<>();
        
for (int i = firstOpeningCurly; i < test.length(); i  ) {
    char next = test.charAt(i);
            
    if (next == '{') brackets.push('{');
    if (i == firstOpeningCurly) continue;
            
    if (next == '}') brackets.pop();
            
    if (i != firstOpeningCurly && brackets.isEmpty()) break;
            
    testTwoText.append(next);
}
    
System.out.println(testTwoText);

Output:

 My Text Two
   sub_test_one{
     My Sub Text
    }
   sub_test_two{
     My Sub Text
    }
  • Related