Manya
Manya

Reputation: 315

JavaScript - Extract JSON from log file

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];

Upvotes: 2

Views: 2665

Answers (2)

Alex K
Alex K

Reputation: 3231

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/

Upvotes: 2

SvenT
SvenT

Reputation: 11

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.

Upvotes: 1

Related Questions