Regex to match key value pairs from JSON - java

I need to match all the key values pairs from a complex JSON, but only values that are text / String.
For example from:
{"results":[
{"id":16,"name":"some name1","location":"some location1","parent":true, ,"region":"some region"},
{"id":157,"name":"some name2" , "location":some location2","parent":true}
],"totalCount":170}
I need to match:
"name"
"some name1"
"location"
"some location1"
"region"
"some region1"
etc
I have this [^:]+\"(?=[,}\s]|$) , but it only matches the values (which are correct).
I need also to match the keys: "name" , "location", "region" (and there can be other key names)
Here is an example for values matched https://regex101.com/r/m8FePZ/6

As others pointed out, if you want a robust solution use a JSON parser in your language.
If you want to use regex, and the engine supports lookbehind you can use this:
/("[^"]*"(?=:")|(?<=":)"[^"]*")/g
Explanation:
| - or combination of:
"[^"]*"(?=:") - quote, 0+ non-quotes, quote, followed by positive lookahead for colon and quote
(?<=":)"[^"]*" - positive lookbehind for quote and colon, followed by quote, 0+ non-quotes, quote
If you want to exclude the quotes in the matches, use this regex:
/(?<=")([^"]*(?=":")|(?<=":")[^"]*)/g
Note that these regexes fail for cover corner cases, such as whitespace around keys and values, escaped quotes in values, etc. Hence it is safer to use an actual JSON parser.

I saw that you decided not to use regex and used JSON library finally. Here is the simple solution by "Josson & Jossons".
https://github.com/octomix/josson
implementation 'com.octomix.josson:josson:1.3.22'
---------------------------------------------
Josson josson = Josson.fromJsonString(
"{\n" +
" \"results\": [\n" +
" {\n" +
" \"id\": 16,\n" +
" \"name\": \"some name1\",\n" +
" \"location\": \"some location1\",\n" +
" \"parent\": true,\n" +
" \"region\": \"some region\"\n" +
" },\n" +
" {\n" +
" \"id\": 157,\n" +
" \"name\": \"some name2\",\n" +
" \"location\": \"some location2\",\n" +
" \"parent\": true\n" +
" }\n" +
" ],\n" +
" \"totalCount\": 170\n" +
"}");
JsonNode node = josson.getNode(
"results.entries().[value.isText()]*.toArray()");
System.out.println(node.toPrettyString());
Output
[ "name", "some name1", "location", "some location1", "region", "some region", "name", "some name2", "location", "some location2" ]

Related

UpperCase all json keys using java and regex to find the matches

I'm beginner in java and have to replace all json Keys to upper Case .
My json can contain arrays (maybe nested Ones) and objects
Here is an example of my json input :
{
"transactionId": 181,
"Shipments": [
{
"shipmentId": 2,
"picklistId": "24RZ",
"ExtOrderId": "23-127",
"boxType": "120"
}
]
}
Here is an example of my json Output :
{
"TRANSACTIONID": 181,
"SHIPMENTS": [
{
"SHIPMENTID": 2,
"PICKLISTID": "24RZ",
"EXTORDERID": "23-127",
"BOXTYPE": "120"
}
]
}
I have tried to create an adapter but no chance to make it work correctly ,
Do i Have to use a regex and a replaceAll("everything before a : " , "upperCase()")
I'm reaching out to you guys to help me on this task because i could not find a way out to find a solution
One of the solutions is to flatten the JSON, upperCase() the keys and unflatten the JSON. Library Josson can do the transformation.
https://github.com/octomix/josson
Josson josson = Josson.fromJsonString(
"{" +
" \"transactionId\": 181," +
" \"Shipments\": [" +
" {" +
" \"shipmentId\": 2," +
" \"picklistId\": \"24RZ\"," +
" \"ExtOrderId\": \"23-127\"," +
" \"boxType\": \"120\"" +
" }" +
" ]" +
"}");
JsonNode node = josson.getNode(
"flatten('.').entries().map(key.upperCase()::value).mergeObjects().unflatten('.')");
System.out.println(node.toPrettyString());
Output
{
"TRANSACTIONID" : 181,
"SHIPMENTS" : [ {
"SHIPMENTID" : 2,
"PICKLISTID" : "24RZ",
"EXTORDERID" : "23-127",
"BOXTYPE" : "120"
} ]
}

Querying JSON Object in Java

Suppose my JSON is :
{
"Name" : "Anmol Jain",
"Address" : [
{
"type" : "home",
"category" : "primary",
"street" : "ABC"
},
{
"type" : "home",
"category" : "secondary",
"street" : "XYZ"
},
{
"type" : "work",
"category" : "primary",
"street" : "PQR"
}
]
}
I am designing a specific syntax for my project so that I can query the JSON.
For Example :
Address(type = home; category = secondary).street
this should give me result as "XYZ".
The first approach that comes to my mind is to parse the above code syntax, and look for conditions like type and category (by string parsing).
then loop through Address array and try to match those conditions. But this will give higher time complexity in case of large JSONs.
Is there any library which does that. Or if anyone can suggest me better approach. The syntax for the condition is flexible and I can mould it accordingly.
Thanks in advance.
For example, use library "Josson & Jossons"
https://github.com/octomix/josson
implementation 'com.octomix.josson:josson:1.3.22'
------------------------------------------------
Josson josson = Josson.fromJsonString(
"{" +
" \"Name\" : \"Anmol Jain\"," +
" \"Address\" : [" +
" {" +
" \"type\" : \"home\"," +
" \"category\" : \"primary\"," +
" \"street\" : \"ABC\"" +
" }," +
" {" +
" \"type\" : \"home\"," +
" \"category\" : \"secondary\"," +
" \"street\" : \"XYZ\"" +
" }," +
" {" +
" \"type\" : \"work\"," +
" \"category\" : \"primary\"," +
" \"street\" : \"PQR\"" +
" }" +
" ]" +
"}");
String street = josson.getString("Address[type='home' & category='secondary'].street");
Besides #tgdavies mentioned, also have a look at https://github.com/eiiches/jackson-jq, it uses the same syntax of jq, but in java implementation.

How to parse only 1 variable from JSON HTTP response Spring Boot

Hi I would like to parse only 1 value from GET response in the most optimal way using Java (+Spring Boot).
{
"table": "A",
"currency": "usd",
"code": "USD",
"rates": [
{
"no": "073/A/NBP/2021",
"effectiveDate": "2021-04-16",
"mid": 3.7978
}
]
}
Im looking for way to parse "mid" value without creating DTO for this response. In the worst case I will do just a substring.
Try this.
String input = "{\r\n"
+ " \"table\": \"A\",\r\n"
+ " \"currency\": \"usd\",\r\n"
+ " \"code\": \"USD\",\r\n"
+ " \"rates\": [\r\n"
+ " {\r\n"
+ " \"no\": \"073/A/NBP/2021\",\r\n"
+ " \"effectiveDate\": \"2021-04-16\",\r\n"
+ " \"mid\": 3.7978\r\n"
+ " }\r\n"
+ " ]\r\n"
+ "}";
String midValue = input.replaceFirst("(?s).*\"mid\"\\s*:\\s*([-.\\d]+).*", "$1");
System.out.println(midValue);
output:
3.7978

Java regex to split along words, punctuation, and whitespace, and keep all in an array

I am trying to split a sentence into a group of strings. I want to keep all words, punctuation and whitespace in an array.
For example:
"Hello! My name is John Doe."
Would be split into:
["Hello", "!", " ", "My", " ", "name", " ", "is", " ", "John", " ", "Doe"]
I currently have the following line of code breaking my sentence:
String[] fragments = sentence.split("(?<!^)\\b");
However, this is running into an error where it counts a punctuation mark followed by a whitespace as a single string. How do I modify my regex to account for this?
You can try the following regular expression:
(?<=\b|[^\p{L}])
"Hello! My name is John Doe.".split("(?<=\\b|[^\\p{L}])", 0)
// ⇒ ["Hello", "!", " ", "My", " ", "name", " ", "is", " ", "John", " ", "Doe", "."]

Compare JSON with nested arrays and jsons (Array order does not matter)

Hello I'm trying to compare two json in java, each key can contain a json object or array of json objects, and each one of them can also be an array or json.
Here is an example of the Json:
{
"id": "123123asd123",
"attributes": [
{
"name": "apps",
"values": [
"111",
"222"
]
},
{
"name": "city",
"values": [
"NY"
]
}
]
}
I want to be able to get two json from this kind and compare them without caring about the order of the arrays.
As you can see the key 'attributes is an array of json so if i have another json like the one up here and the element in the array with key city is before apps i want the test to pass.
aswell of the numbers inside the apps values i dont care if it is 111,222 or 222,111
If anyone know any external java lib that is doing that ill be happy hear.
Or any idea how to implement this compare manually? or even an idea that will this kind of json and reorganize it so it will be easy to compare share that with me.
Take a look at this library she is cool i'm using it all the day for my Webservice Test:
https://github.com/jayway/JsonPath
#Test
public void test() {
String json = "{\n" +
" \"id\": \"123123asd123\",\n" +
" \"attributes\": [\n" +
" {\n" +
" \"name\": \"apps\",\n" +
" \"values\": [\n" +
" \"111\",\n" +
" \"222\"\n" +
" ]\n" +
" },\n" +
" {\n" +
" \"name\": \"city\",\n" +
" \"values\": [\n" +
" \"NY\"\n" +
" ]\n" +
" }\n" +
" ]\n" +
"}";
List<String> names = JsonPath.read(json, "$.attributes[*].name");
for(String name : names) {
//TODO assert that name is in other list from other json
}

Categories