0

I have a large text file. Its mixed up more lines with various info

My requirement is retrieve json from Below mixed String line

Line :

PID: [0] [STM] [2016-12-01 00:00:00,135]  INFORMATION {com.priyan.JsonParser} -  My Req Body: { "amountTxn": { "paymentAmt": { "amtReserved": null, "totalAmtCharged": null, "chargingData": { "taxAmt": 10, "categoryCode": "MyApp" }, "totalAmountRefunded": null, "chargingInformation": { "amount": 1.5, "description": ["Test 01 (demo)"] } }, "userId": "tel:+2313215", "txnStatus": "Charged", "origCode": null, "seq": null } } TOKEN ID: 351351 {com.priyan.JsonParser}

I need to extract this json part only

{ "amountTxn": { "paymentAmt": { "amtReserved": null, "totalAmtCharged": null, "chargingData": { "taxAmt": 10, "categoryCode": "MyApp" }, "totalAmountRefunded": null, "chargingInformation": { "amount": 1.5, "description": ["Test 01 (demo)"] } }, "userId": "tel:+2313215", "txnStatus": "Charged", "origCode": null, "seq": null } }

Please help, Thanks

Priyanka
  • 341
  • 3
  • 13

5 Answers5

5

There are two ways to achieve the solution:

  1. Using Regex
  2. Write your own parser to achieve the solution

Using Regex

Regex is not the recommended solution: They can be very inefficient sometimes. See this and this.

Even if you want regex, here is the solution:

see this

Write your own parser to achieve the solution:

void getJsonFromString(String input) {

        List<Character> stack = new ArrayList<Character>();
        List<String> jsons = new ArrayList<String>();
        String temp = "";
        for(char eachChar: input.toCharArray()) {
            if(stack.isEmpty() && eachChar == '{') {
                stack.add(eachChar);
                temp += eachChar;
            } else if(!stack.isEmpty()) {
                temp += eachChar;
                if(stack.get(stack.size()-1).equals('{') && eachChar == '}') {
                    stack.remove(stack.size()-1);
                    if(stack.isEmpty()) {
                        jsons.add(temp);
                        temp = "";
                    }
                }
                else if(eachChar == '{' || eachChar == '}')
                    stack.add(eachChar);
            } else if(temp.length()>0 && stack.isEmpty()) {
                jsons.add(temp);
                temp = "";
            }
        }
        for(String json: jsons)
            System.out.println(json);
    }
arctic_Oak
  • 974
  • 2
  • 13
  • 29
4

This will find the position of the second bracket you need (because of INFORMATION and TOKEN block) and substring the content you need.

So basicly, I search the second (by finding the bracket after the first one) and same thing for the end. Then simply extract the String.

public static void main(String[] args){
        String s = "PID: [0] [STM] [2016-12-01 00:00:00,135]  INFORMATION {com.priyan.JsonParser} -  My Req Body: { \"amountTxn\": { \"paymentAmt\": { \"amtReserved\": null, \"totalAmtCharged\": null, \"chargingData\": { \"taxAmt\": 10, \"categoryCode\": \"MyApp\" }, \"totalAmountRefunded\": null, \"chargingInformation\": { \"amount\": 1.5, \"description\": [\"Test 01 (demo)\"] } }, \"userId\": \"tel:+2313215\", \"txnStatus\": \"Charged\", \"origCode\": null, \"seq\": null } } TOKEN ID: 351351 {com.priyan.JsonParser}";
        int begin = s.indexOf("{", s.indexOf("{") + 1);
        int end = s.lastIndexOf("}", s.lastIndexOf("}") - 1);
        s = s.substring(begin, end);
        System.out.println(s);
    }

This solution doesn't work if the text before and/or after don't have any bracket but can be update depending on other pattern.

AxelH
  • 14,325
  • 2
  • 25
  • 55
  • thnkz AxelH.This one works for me. can't use Json or Gson libraries for this task.? – Priyanka Dec 06 '16 at 09:37
  • 1
    To extract the JSON from the String, I don't think so but I don't know everything about GSON. But is it really necessary, I mean the extraction is not really complicated. – AxelH Dec 06 '16 at 10:11
3

You can use the regular expression ^.*Body:\s(.*)\sTOKEN.* to extract the data you want, provided the adjacent words on either side of the JSON data won't change and I mean exactly the words "Body: " (including the white space) and " TOKEN"

This regex basically extracts the text between "Body: " and " TOKEN"

Rakesh
  • 4,264
  • 4
  • 32
  • 58
  • Noted & Thanks But I need to know whther any other options gave by Json libraries or not.! – Priyanka Dec 06 '16 at 09:19
  • 1
    Yes, like @CodeRunner mentions there are few JSON libs that can parse JSON string and create an object out of it. The problem is that your input string is not a valid JSON string. If you are reading this string from third party data then you are most probably out of luck. – Rakesh Dec 06 '16 at 09:26
  • its correct json. I tested with jsonlint web site too – Priyanka Dec 06 '16 at 09:36
  • 1
    I tested the entire string starting from `PID: [0] ... ` on jsonlint and it gave validation error. – Rakesh Dec 06 '16 at 09:39
  • not entire string. from entire string i need to extract only that below json part – Priyanka Dec 06 '16 at 09:43
  • In my case, I have a String which may contain multiple '{' or '}' which are not part of JSON. There is no fixed word before or after JSON. Is there any regex pattern to extract JSON from such String. The String contains only one valid JSON but rest of the content in String can be anything. – abi_pat May 18 '17 at 04:40
2

Create a class which has a structure similar to JSON and then use Jackson [Java JSON parser (http://jackson.codehaus.org)] library. Please refer Parsing JSON File Java for more information

CodeRunner
  • 139
  • 7
1

If the line has a fixed pattern, you just have to get the part between "My Req Body" and "JSON". It's easy.

If the line does not have a fixed pattern, you can start with the first index of "{" and move forward to build the JSON string. You need to count for the number of open curly brackets and stop getting the string when you reach the same number of closed bracket. After having the string, you can use the library like gson to validate if it's a valid JSON string.

Duy Nguyen
  • 531
  • 2
  • 5