2

I need to extract JSON string (which will be used later to parse JSON) from a log file. The file is in this format:

[16:11:20] some text
[16:11:20] some text
some text
some text
[
  {
    "description": "some text",
    "elements": [{
        "id": "some text",
        "keyword": "some text",
        "line": 20,
        "name": "some text",
        "steps": [{
            "arguments": [],
            "keyword": "some text ",
            "result": {
                "status": "passed",
                "duration": 14884761888
            },
            "hidden": true,
            "match": {
                "location": "some text"
            }
        },
        {
            "arguments": [],
            "keyword": "sometext ",
            "name": "sometext",
            "result": {
                "status": "passed",
                "duration": 463674
            },
            "line": 11,
            "match": {
                "location": "sometext"
            }
        }
        ],
        "tags": [
          {
            "name": "@sometext-no",
            "line": 7
          },
          {
            "name": "@sometext",
            "line": 8
          }
        ],
        "type": "sometext"
      }

    ],
    "id": "sometext",
    "keyword": "sometext",
    "line": 1,
    "name": "sometext",
    "tags": [],
    "uri": "sometext"
  }
][16:11:54] some text
[16:11:54] some text

How can I construct a regex in JavaScript which will extract JSON data from this file so that it can be used by string.match() to give the desired output

The pattern I am trying is as below

var regExtract = /(\[\s+\{[\s\S]*\}\s+\]\s+\}\s+\]\s+\}\s+\])/;
var matchedJson = data.toString().match(regExtract)[1];
4
  • So, is that pattern not working? Note that \s+ means "one or more whitespace characters", so that means your pattern will not match your example. You also have the end of your pattern, }] several times. Commented Jul 19, 2016 at 20:15
  • Here's a patter which matches the provided format: regex101.com/r/uU9oI0/1 Commented Jul 19, 2016 at 20:17
  • Would that "json" data string always be placed on a separate line? Commented Jul 19, 2016 at 20:24
  • updated the qs with sample log file from which JSON is to be extracted Commented Jul 19, 2016 at 22:37

2 Answers 2

2

I update my answer, you can try something like that:

var str = `[16:11:20] some text
[16:11:20] some text
some text
some text
[
  {
    "description": "some text",
    "elements": [{
        "id": "some text",
        "keyword": "some text",
        "line": 20,
        "name": "some text",
        "steps": [{
            "arguments": [],
            "keyword": "some text ",
            "result": {
                "status": "passed",
                "duration": 14884761888
            },
            "hidden": true,
            "match": {
                "location": "some text"
            }
        },
        {
            "arguments": [],
            "keyword": "sometext ",
            "name": "sometext",
            "result": {
                "status": "passed",
                "duration": 463674
            },
            "line": 11,
            "match": {
                "location": "sometext"
            }
        }
        ],
        "tags": [
          {
            "name": "@sometext-no",
            "line": 7
          },
          {
            "name": "@sometext",
            "line": 8
          }
        ],
        "type": "sometext"
      }

    ],
    "id": "sometext",
    "keyword": "sometext",
    "line": 1,
    "name": "sometext",
    "tags": [],
    "uri": "sometext"
  }
][16:11:54] some text
[16:11:54] some text
`;

var json = '';
var jsonArray = [];
var implode = false;
str.split('\n').forEach(function(v, k){   
  if(v === '  {'){
    console.log(k, v);
    implode = true;
  }

  if(implode){
    json = json + v + '\n';
  }

  if(v === '  }'){      
    console.log(k, v);
    implode = false;
    jsonArray.push(json.trim());
    json = '';

    console.log(jsonArray);    
  }
});
console.log(JSON.parse(jsonArray[0]));

Fiddle: https://jsfiddle.net/x0cc25q4/7/

UPDATE: Short version with regex:

var arr = str.split('\n').join('').match(/\[\s{2}(\{.*?\})\]/g);
console.log(JSON.parse(arr[0]));

Fiddle: https://jsfiddle.net/x0cc25q4/8/

Sign up to request clarification or add additional context in comments.

3 Comments

This solution is fine but I was wondering if there is any regex way of doing it as that would reduce the code drastically.
Extremely short version for you :)
Glad it worked ! Please accept the answer as it would help others who have the same question, thank you :)
1

not sure this works with regexp only since you need to count opening and closing brackets. try

var start=string.indexOf('[{');
var level=1;
start++;
while (level>0){
   if (string[start]==='[') level++;
   if (string[start]===']') level--;
   start++;
}

this surely gets more complicated if there could be '[' or ']' within strings in the json.

1 Comment

You also need to count opening/closing curly braces, in case there are nested objects.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.