Split JSON objects in array string using regex - java

I have a String in the following format:
[{"HostName":"taskmanager1","Rack":"/default-rack","State":"RUNNING","NodeId":"taskmanager1:45454","NodeHTTPAddress":"taskmanager1:8042","LastHealthUpdate":1519568501615,"HealthReport":"","NodeManagerVersion":"2.8.3","NumContainers":0,"UsedMemoryMB":0,"AvailableMemoryMB":1024},{"HostName":"datanode2","Rack":"/default-rack","State":"RUNNING","NodeId":"datanode2:45454","NodeHTTPAddress":"datanode2:8042","LastHealthUpdate":1519260876106,"HealthReport":"","NodeManagerVersion":"2.8.3","NumContainers":0,"UsedMemoryMB":0,"AvailableMemoryMB":1024},{"HostName":"taskmanager3","Rack":"/default-rack","State":"RUNNING","NodeId":"taskmanager3:45454","NodeHTTPAddress":"taskmanager3:8042","LastHealthUpdate":1519568502251,"HealthReport":"","NodeManagerVersion":"2.8.3","NumContainers":0,"UsedMemoryMB":0,"AvailableMemoryMB":1024},{"HostName":"datanode3","Rack":"/default-rack","State":"RUNNING","NodeId":"datanode3:45454","NodeHTTPAddress":"datanode3:8042","LastHealthUpdate":1519260871527,"HealthReport":"","NodeManagerVersion":"2.8.3","NumContainers":0,"UsedMemoryMB":0,"AvailableMemoryMB":1024},{"HostName":"taskmanager2","Rack":"/default-rack","State":"RUNNING","NodeId":"taskmanager2:45454","NodeHTTPAddress":"taskmanager2:8042","LastHealthUpdate":1519568502259,"HealthReport":"","NodeManagerVersion":"2.8.3","NumContainers":0,"UsedMemoryMB":0,"AvailableMemoryMB":1024},{"HostName":"datanode1","Rack":"/default-rack","State":"RUNNING","NodeId":"datanode1:45454","NodeHTTPAddress":"datanode1:8042","LastHealthUpdate":1519260875647,"HealthReport":"","NodeManagerVersion":"2.8.3","NumContainers":0,"UsedMemoryMB":0,"AvailableMemoryMB":1024}]
I want to split it into multiple (here 6) JSON format, but my pattern cannot split that as desired.
I want something like this:
{"HostName":"taskmanager1","Rack":"/default-rack","State":"RUNNING","NodeId":"taskmanager1:45454","NodeHTTPAddress":"taskmanager1:8042","LastHealthUpdate":1519568501615,"HealthReport":"","NodeManagerVersion":"2.8.3","NumContainers":0,"UsedMemoryMB":0,"AvailableMemoryMB":1024},
{"HostName":"datanode2","Rack":"/default-rack","State":"RUNNING","NodeId":"datanode2:45454","NodeHTTPAddress":"datanode2:8042","LastHealthUpdate":1519260876106,"HealthReport":"","NodeManagerVersion":"2.8.3","NumContainers":0,"UsedMemoryMB":0,"AvailableMemoryMB":1024},
{"HostName":"taskmanager3","Rack":"/default-rack","State":"RUNNING","NodeId":"taskmanager3:45454","NodeHTTPAddress":"taskmanager3:8042","LastHealthUpdate":1519568502251,"HealthReport":"","NodeManagerVersion":"2.8.3","NumContainers":0,"UsedMemoryMB":0,"AvailableMemoryMB":1024},
{"HostName":"datanode3","Rack":"/default-rack","State":"RUNNING","NodeId":"datanode3:45454","NodeHTTPAddress":"datanode3:8042","LastHealthUpdate":1519260871527,"HealthReport":"","NodeManagerVersion":"2.8.3","NumContainers":0,"UsedMemoryMB":0,"AvailableMemoryMB":1024}
,{"HostName":"taskmanager2","Rack":"/default-rack","State":"RUNNING","NodeId":"taskmanager2:45454","NodeHTTPAddress":"taskmanager2:8042","LastHealthUpdate":1519568502259,"HealthReport":"","NodeManagerVersion":"2.8.3","NumContainers":0,"UsedMemoryMB":0,"AvailableMemoryMB":1024},
{"HostName":"datanode1","Rack":"/default-rack","State":"RUNNING","NodeId":"datanode1:45454","NodeHTTPAddress":"datanode1:8042","LastHealthUpdate":1519260875647,"HealthReport":"","NodeManagerVersion":"2.8.3","NumContainers":0,"UsedMemoryMB":0,"AvailableMemoryMB":1024}
Using the code:
List<String> res = Arrays.asList(temp.replace('[', ' ').replace(']',' ').trim()).split(",");
It will be split for every , character and using the pattern split("},\\}") will remove } and { character, too.
How can I split that as desire to make Json objects?
Using the Java pattern (\\{.+}) will group whole string.

You can parse the JSON as an array and treat the contents as individual strings. Here is sample code:
import org.json.JSONArray;
public class orgJson1Main {
private static final String sample = "[{\"HostName\":\"taskmanager1\",\"Rack\":\"/default-rack\",\"State\":\"RUNNING\",\"NodeId\":\"taskmanager1:45454\",\"NodeHTTPAddress\":\"taskmanager1:8042\",\"LastHealthUpdate\":1519568501615,\"HealthReport\":\"\",\"NodeManagerVersion\":\"2.8.3\",\"NumContainers\":0,\"UsedMemoryMB\":0,\"AvailableMemoryMB\":1024},{\"HostName\":\"datanode2\",\"Rack\":\"/default-rack\",\"State\":\"RUNNING\",\"NodeId\":\"datanode2:45454\",\"NodeHTTPAddress\":\"datanode2:8042\",\"LastHealthUpdate\":1519260876106,\"HealthReport\":\"\",\"NodeManagerVersion\":\"2.8.3\",\"NumContainers\":0,\"UsedMemoryMB\":0,\"AvailableMemoryMB\":1024},{\"HostName\":\"taskmanager3\",\"Rack\":\"/default-rack\",\"State\":\"RUNNING\",\"NodeId\":\"taskmanager3:45454\",\"NodeHTTPAddress\":\"taskmanager3:8042\",\"LastHealthUpdate\":1519568502251,\"HealthReport\":\"\",\"NodeManagerVersion\":\"2.8.3\",\"NumContainers\":0,\"UsedMemoryMB\":0,\"AvailableMemoryMB\":1024},{\"HostName\":\"datanode3\",\"Rack\":\"/default-rack\",\"State\":\"RUNNING\",\"NodeId\":\"datanode3:45454\",\"NodeHTTPAddress\":\"datanode3:8042\",\"LastHealthUpdate\":1519260871527,\"HealthReport\":\"\",\"NodeManagerVersion\":\"2.8.3\",\"NumContainers\":0,\"UsedMemoryMB\":0,\"AvailableMemoryMB\":1024},{\"HostName\":\"taskmanager2\",\"Rack\":\"/default-rack\",\"State\":\"RUNNING\",\"NodeId\":\"taskmanager2:45454\",\"NodeHTTPAddress\":\"taskmanager2:8042\",\"LastHealthUpdate\":1519568502259,\"HealthReport\":\"\",\"NodeManagerVersion\":\"2.8.3\",\"NumContainers\":0,\"UsedMemoryMB\":0,\"AvailableMemoryMB\":1024},{\"HostName\":\"datanode1\",\"Rack\":\"/default-rack\",\"State\":\"RUNNING\",\"NodeId\":\"datanode1:45454\",\"NodeHTTPAddress\":\"datanode1:8042\",\"LastHealthUpdate\":1519260875647,\"HealthReport\":\"\",\"NodeManagerVersion\":\"2.8.3\",\"NumContainers\":0,\"UsedMemoryMB\":0,\"AvailableMemoryMB\":1024}]";
public static void main(String[] args) {
JSONArray array = new JSONArray(sample);
for(int i=0; i < array.length(); i++){
System.out.println(array.get(i));
}
}
}
OUTPUT:
{"NodeManagerVersion":"2.8.3","Rack":"/default-rack","LastHealthUpdate":1519568501615,"HealthReport":"","State":"RUNNING","AvailableMemoryMB":1024,"NodeId":"taskmanager1:45454","UsedMemoryMB":0,"NodeHTTPAddress":"taskmanager1:8042","HostName":"taskmanager1","NumContainers":0}
{"NodeManagerVersion":"2.8.3","Rack":"/default-rack","LastHealthUpdate":1519260876106,"HealthReport":"","State":"RUNNING","AvailableMemoryMB":1024,"NodeId":"datanode2:45454","UsedMemoryMB":0,"NodeHTTPAddress":"datanode2:8042","HostName":"datanode2","NumContainers":0}
{"NodeManagerVersion":"2.8.3","Rack":"/default-rack","LastHealthUpdate":1519568502251,"HealthReport":"","State":"RUNNING","AvailableMemoryMB":1024,"NodeId":"taskmanager3:45454","UsedMemoryMB":0,"NodeHTTPAddress":"taskmanager3:8042","HostName":"taskmanager3","NumContainers":0}
{"NodeManagerVersion":"2.8.3","Rack":"/default-rack","LastHealthUpdate":1519260871527,"HealthReport":"","State":"RUNNING","AvailableMemoryMB":1024,"NodeId":"datanode3:45454","UsedMemoryMB":0,"NodeHTTPAddress":"datanode3:8042","HostName":"datanode3","NumContainers":0}
{"NodeManagerVersion":"2.8.3","Rack":"/default-rack","LastHealthUpdate":1519568502259,"HealthReport":"","State":"RUNNING","AvailableMemoryMB":1024,"NodeId":"taskmanager2:45454","UsedMemoryMB":0,"NodeHTTPAddress":"taskmanager2:8042","HostName":"taskmanager2","NumContainers":0}
{"NodeManagerVersion":"2.8.3","Rack":"/default-rack","LastHealthUpdate":1519260875647,"HealthReport":"","State":"RUNNING","AvailableMemoryMB":1024,"NodeId":"datanode1:45454","UsedMemoryMB":0,"NodeHTTPAddress":"datanode1:8042","HostName":"datanode1","NumContainers":0}
EDIT:
First, I removed the JSONTokener from the above code. Second, for completeness I'm adding the following code that shows how to find the individual JSON objects within the sample string using a regex as originally asked.
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class orgJson1Main {
private static final String sample = "[{\"HostName\":\"taskmanager1\",\"Rack\":\"/default-rack\",\"State\":\"RUNNING\",\"NodeId\":\"taskmanager1:45454\",\"NodeHTTPAddress\":\"taskmanager1:8042\",\"LastHealthUpdate\":1519568501615,\"HealthReport\":\"\",\"NodeManagerVersion\":\"2.8.3\",\"NumContainers\":0,\"UsedMemoryMB\":0,\"AvailableMemoryMB\":1024},{\"HostName\":\"datanode2\",\"Rack\":\"/default-rack\",\"State\":\"RUNNING\",\"NodeId\":\"datanode2:45454\",\"NodeHTTPAddress\":\"datanode2:8042\",\"LastHealthUpdate\":1519260876106,\"HealthReport\":\"\",\"NodeManagerVersion\":\"2.8.3\",\"NumContainers\":0,\"UsedMemoryMB\":0,\"AvailableMemoryMB\":1024},{\"HostName\":\"taskmanager3\",\"Rack\":\"/default-rack\",\"State\":\"RUNNING\",\"NodeId\":\"taskmanager3:45454\",\"NodeHTTPAddress\":\"taskmanager3:8042\",\"LastHealthUpdate\":1519568502251,\"HealthReport\":\"\",\"NodeManagerVersion\":\"2.8.3\",\"NumContainers\":0,\"UsedMemoryMB\":0,\"AvailableMemoryMB\":1024},{\"HostName\":\"datanode3\",\"Rack\":\"/default-rack\",\"State\":\"RUNNING\",\"NodeId\":\"datanode3:45454\",\"NodeHTTPAddress\":\"datanode3:8042\",\"LastHealthUpdate\":1519260871527,\"HealthReport\":\"\",\"NodeManagerVersion\":\"2.8.3\",\"NumContainers\":0,\"UsedMemoryMB\":0,\"AvailableMemoryMB\":1024},{\"HostName\":\"taskmanager2\",\"Rack\":\"/default-rack\",\"State\":\"RUNNING\",\"NodeId\":\"taskmanager2:45454\",\"NodeHTTPAddress\":\"taskmanager2:8042\",\"LastHealthUpdate\":1519568502259,\"HealthReport\":\"\",\"NodeManagerVersion\":\"2.8.3\",\"NumContainers\":0,\"UsedMemoryMB\":0,\"AvailableMemoryMB\":1024},{\"HostName\":\"datanode1\",\"Rack\":\"/default-rack\",\"State\":\"RUNNING\",\"NodeId\":\"datanode1:45454\",\"NodeHTTPAddress\":\"datanode1:8042\",\"LastHealthUpdate\":1519260875647,\"HealthReport\":\"\",\"NodeManagerVersion\":\"2.8.3\",\"NumContainers\":0,\"UsedMemoryMB\":0,\"AvailableMemoryMB\":1024}]";
public static void main(String[] args) {
Matcher matcher = Pattern.compile("\\{[^}]*\\}").matcher(sample);
while(matcher.find()){
System.out.println(matcher.group());
}
}
}

To split on }, {, but retain the curly brackets in the tokens, split on this regex:
"(?<=\\}), (?=\\{)"
Which uses a look behind and a look ahead to assert the curly brackets preceed and follow the comma, but not consume them in the split.
The whole line then becomes:
List<String> res = Arrays.asList(temp.replaceAll("^.|.$", "").split("(?<=\\}), (?=\\{)");
Note also the simplified trimming of leading [ and trailing ] but more-simply removing the first and last character in one operation.

If your purpose to use this List as list of MyJsonObject I would recommend to reuse brilliant google gson library.
There is easy way to convert String to List without intermediate manipulation with List.
What you need to follow followed steps.
1) Create your POJO class:
public class POJO
{
String HostName;
String Rack;
String State;
String NodeId;
String NodeHTTPAddress;
String LastHealthUpdate;
String HealthReport;
String NodeManagerVersion;
String NumContainers;
String UsedMemoryMB;
String AvailableMemoryMB;
... getters/setters here ....
}
2) Create gson converter:
Gson gson = (new GsonBuilder() ).create();
3) Create typeToken for list of your POJOs:
Type type = new TypeToken< List<POJO> >(){}.getType();
4) Convert String to desire collection:
List<MyJsonObject> list = gson.fromJson( json, type );

Related

When parse the string to JsonElement, how to avoid auto read escape character?

I have a simple json str like below
{
"foo":"\uv"
}
I want to use gson to parse this str to jsonElement.
eg.
String input = "{\"foo\":\"\\uv\"}";
JsonElement element = JsonParser.parseString(input);
But gson throw the com.google.gson.JsonSyntaxException, java.lang.NumberFormatException: \uv
It seems like when JsonReader meet the '\', it will automaticly treat it as a escape character.So, What can I do to make gson treat it as plain text instead of escape character?
What you want to do should not be possible. Forcing gson to accept \ as plain text would be forcing it to not follow json conventions.
Also your json is not valid, correct one would be:
{
"foo":"\\uv"
}
Check gson adding backslash in string, it has good explanation. Using your code as example:
public class Temp {
public static void main(String[] args) {
String input = "{\"foo\":\"\\\\uv\"}";
JsonElement element = JsonParser.parseString(input);
System.out.println("foo value - " + element.getAsJsonObject().getAsJsonPrimitive("foo").getAsString());
}
}
This prints - foo value - \uv, which should be exactly the value your consumers need.

how to use Java to replace String?(regex)

I hava one jsonString
String target = "[{"nickName":"andy","password":"wei","userword":"weitest32123"}]";
I wish to get
String target = "[{"nickName":"andy","password":"xxx","userword":"xxx"}]";
I want to use the java String method replaceall(regex,"xxx");
how do?
Try this.
String input = "[{\"nickName\":\"andy\",\"password\":\"wei\",\"userword\":\"weitest32123\"}]";
String output = input.replaceAll("(?<=\"(pass|user)word\":\")[^\"]+", "xxx");
System.out.println(output);
output:
[{"nickName":"andy","password":"xxx","userword":"xxx"}]
You can do it with the Positive Lookbehind regexp regex101.com:
public static void main(String... args) {
String str = "\"[{\"nickName\":\"andy\",\"password\":\"wei\",\"userword\":\"weitest32123\"}]\"";
System.out.println(maskPassword(str)); // "[{"nickName":"andy","password":"xxx","userword":"xxx"}]"
}
public static String maskPassword(String str) {
String regex = "(?<=\"(password|userword)\":)(\"[^\"]+\")";
return str.replaceAll(regex, "\"xxx\"");
}
P.S. I strongly recommend you not to do this with json string. This could follow a problem in the future. It's better to parse this json string into an object and then create json back with modification.
E.g. you can use a tool that I wrote gson-utils
This may seem like you're trying to parse some JSON. I'm not sure if casting it to object and then hiding values would be better approach.
But if you really need to do this way, this would be the solution
// You need this 2 imports
//import java.util.regex.Matcher;
//import java.util.regex.Pattern;
String text = "[{\"nickName\":\"andy\",\"password\":\"wei\",\"userword\":\"weitest32123\"}]";
Pattern pattern = Pattern.compile("\"(?<key>password|userword)\":\"(?<value>.*?)\"");
Matcher matcher = pattern.matcher(text);
String result = matcher.replaceAll("\"${key}\":\"xxx\"");
In Regex you need to specify all keys that you want to mask

how to split a javascript returned String object in java

I have a string array of objects which I pulled from javascript into java as a single string . It looks like this .
[
{"sourcevalue":"KRISHNA#IN.IBM.COM","userIdValue":"Krishna L Pappu -
krishnalakshmi","objectId":"A1001001A20E08A74322C03420"},
{"sourcevalue":"KRISHNA#IN.IBM.COM","userIdValue":"Krishna L Pappu -
krishnalakshmi","objectId":"A1001001A20E08A74322C03420"},
{"sourcevalue":"KRISHNA#IN.IBM.COM","userIdValue":"Krishna L Pappu -
krishnalakshmi","objectId":"A1001001A20E08A74322C03420"}
]
Now I want to know how it can be split into objects like below in simple java:
{"sourcevalue":"KRISHNA#IN.IBM.COM","userIdValue":"Krishna L Pappu - krishnalakshmi","objectId":"A1001001A20E08A74322C03420"}
{"sourcevalue":"KRISHNA#IN.IBM.COM","userIdValue":"Krishna L Pappu - krishnalakshmi","objectId":"A1001001A20E08A74322C03420"}
{"sourcevalue":"KRISHNA#IN.IBM.COM","userIdValue":"Krishna L Pappu - krishnalakshmi","objectId":"A1001001A20E08A74322C03420"}
I tried with split method its just too clumsy. Thanks in advance
As #Rabbit has said, create a deserializer. There are many ways to do this, A sample could be:
class SimpleObj {
private String sourceValue;
private String userIdValue;
private String objectId;
... getters, and setters ommited
public static List<SimpleObj> deserializer(String data){
Type objType = new TypeToken<ArrayList<SimpleObj>>() {}.getType();
return new ArrayList<>(new Gson().fromJson(data, objType));
}
}
The method deserializer which takes in a string needs Gson() library to work, so import that to your classpath, the method would help you change the incoming string to a list of object, like the one you desire.
I hope this is helpful.
I used this piece of code to achieve my requirement of deserializing the json object list which I got from Javascript. Hope this helps for requirements of deserializing a list of objects which are retrieved from front end.
#SuppressWarnings("unchecked")
public static AttributeValue[] jsonToObject (String jsonObj, Class gilClass) {
Gson gson = new Gson();
return gson.fromJson(jsonObj, AttributeValue[].class);
}

how to remove the slashes from json key while converting object into string

I'm trying to convert JSON object into string by doing the below
JSONObject object = new JSONObject();
object.put("video", data);
array1.add( object.toString().replace("\\\\"," "));
Actual result
["{\"photos\":\"/contests/1/images/1.png\"}",
{\"photos\":\"/contests/1/images/2.png\"}"]
Expected result
["{"photos":"/contests/1/images/1.png\"}","
{"photos":"/contests/1/images/2.png\"}"]
not able to remove the slashes from key
Use replaceAll instead of replace
replaceAll("\\\\", "")
When you want to replace all the occurences with .replace, the first parameter must be a regex, if you supply a string, only the first occurrence will be replaced, that's why your replace wouldn't work.
Please use:
.replace("/\\/g","")
Alternatively, replaceAll can be used as #Code_Mono suggested
The Code_Mode mentioned is correct one.
Because String is immutable. Make sure that you put it right place.
You can refer code bellow for more detail:
public static void main(String[] args) {
String json = "[\"{\\\"photos\\\":\\\"/contests/1/images/1.png\\\"}\", {\\\"photos\\\":\\\"/contests/1/images/2.png\\\"}\"]";
json.replaceAll("\\\\","");
System.out.println(json);
String jsonReplace = json.replaceAll("\\\\","");
System.out.println(jsonReplace);
}
Output value:
["{\"photos\":\"/contests/1/images/1.png\"}", {\"photos\":\"/contests/1/images/2.png\"}"]
["{"photos":"/contests/1/images/1.png"}", {"photos":"/contests/1/images/2.png"}"]

How to add two JSON formatted Java Strings together?

I have two JSON Format Strings
{"user1":{"Iden":4,"nID":1},"user2":{"Iden":5,"nID":1}} // String A JSON
{"user1":{"Iden":4,"nID":1},"user3":{"Iden":6,"nID":1},"user2":{"Iden":5,"nID":1}}
In the below program these above JSON are formatted by Eclipse IDE
This is my program:
import java.util.Map;
import org.codehaus.jackson.type.TypeReference;
import com.tradeking.at.util.JsonHelper;
public class Hi {
private static JsonHelper jsonHelper = JsonHelper.getInstance();
public static void main(String[] args) throws Exception {
Map<String, Tracker> totalCusts = null;
String A = "{\"user1\":{\"Iden\":4,\"nID\":1},\"user2\":{\"Iden\":5,\"nID\":1}}";
String B = "{\"user1\":{\"Iden\":4,\"nID\":1},\"user3\":{\"Iden\":6,\"nID\":1},\"user2\":{\"Iden\":5,\"nID\":1}}";
String totalString = A+B;
if (null != totalString) {
totalCusts = (Map<String, Tracker>) jsonHelper.toObject(
totalString, new TypeReference<Map<String, Tracker>>() {
});
}
System.out.println(totalCusts);
}
}
Tracker.java:
import org.json.JSONObject;
public class Tracker extends JSONObject{
}
When i ran the above , the Output is
{user1={}, user2={}}
if I use this:
String totalString = B + A ;
The O/p is:
{user1={}, user3={}, user2={}}
Please let me know how I can add two JSON Strings??
At the top-level, a JSON document is always a single object, array, or value. By just concatenating the two strings together, you're violating this principal. A simple workaround would be to join the two values together in an array:
String totalString = "[" + A + ", " + B + "]";
And then parse as such. Or you could simply parse each JSON document one at a time, and then append or merge your results (I suspect you want to merge them, via Map.putAll).
Given that the values for your userN keys are empty, you probably have a bug in your JsonHelper class, but that's hard to say without seeing the code.

Categories

Resources