Reputation: 53
I have a string
value as below
String str = {"A":"do not seperate,value","B":"OPM","C":[1,2,"AB",{"1":{"1":2,"2":[1,2]},"2":2}],"D":{"1":1,"2":[{"1":1,"2":2,"3":3},9,10]}};
How can I write a regular expression to capture its elements separated by a comma which is not inside double quotes, square brackets or curly brackets? I want to match and get the elements by doing something like below; using pattern matching.
List<String> list = new ArrayList<>();
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(str);
while (matcher.find()) {
list.add(matcher.group());
}
The elements should be,
"A":"do not seperate,value"
"B":"OPM"
"C":[1,2,"AB",{"1":{"1":2,"2":[1,2]},"2":2}]
"D":{"1":1,"2":[{"1":1,"2":2,"3":3},9,10]}
If the string is something like below
String str = [1,2,{"A":1,"B":2},[19,10,11,{"A":1,"B":2}],100]
Then the elements should be
1
2
{"A":1,"B":2}
[19,10,11,{"A":1,"B":2}]
100
Upvotes: 2
Views: 340
Reputation: 161
You probably can do something like this
public static List<String> getStringElements(String str) {
List<String> elementsList = new ArrayList<>();
StringBuilder element = new StringBuilder();
int bracketsCount = 0;
int quotesCount = 0;
char[] strChars = str.substring(1, str.length() - 1).toCharArray();
for (char strChar : strChars) {
element.append(strChar);
if (strChar == '\"') {
quotesCount++;
} else if (strChar == '[' && quotesCount % 2 == 0) {
bracketsCount++;
} else if (strChar == '{' && quotesCount % 2 == 0) {
bracketsCount++;
} else if (strChar == '(' && quotesCount % 2 == 0) {
bracketsCount++;
} else if (strChar == ']' && quotesCount % 2 == 0) {
bracketsCount--;
} else if (strChar == '}' && quotesCount % 2 == 0) {
bracketsCount--;
} else if (strChar == ')' && quotesCount % 2 == 0) {
bracketsCount--;
} else if (strChar == ',' && bracketsCount == 0 && quotesCount % 2 == 0) {
elementsList.add(element.substring(0, element.length() - 1));
element = new StringBuilder();
}
}
if (element.length() > 0) {
elementsList.add(element.toString());
}
return elementsList;
}
Upvotes: 1
Reputation: 548
Since its a json string you can parse it with object mapper and get them as key value pair in a hashmap.
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
import java.util.*;
import org.json.JSONObject;
public class Test {
public static void main(String args[]) throws IOException {
String str = "{\"A\":\"do not seperate,value\",\"B\":\"OPM\",\"C\":[1,2,\"AB\",{\"1\":{\"1\":2,\"2\":[1,2]},\"2\":2}],\"D\":{\"1\":1,\"2\":[{\"1\":1,\"2\":2,\"3\":3},9,10]}}";
JSONObject obj = new JSONObject(str);
HashMap<String, Object> result = new ObjectMapper().readValue(str, new TypeReference<Map<String, Object>>() {
});
result.entrySet().stream().forEach(System.out::println);
}
}
output
A=do not seperate,value
B=OPM
C=[1, 2, AB, {1={1=2, 2=[1, 2]}, 2=2}]
D={1=1, 2=[{1=1, 2=2, 3=3}, 9, 10]}
Upvotes: 1