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
}