Reputation: 683
I have this text
parent( child( child_of_child(value) ) )
and this regex pattern to math with
([a-z]+\(.*\))
Javascript code I use
'parent( child( child_of_child(value) ) )'.match(/([a-z]+\(.*\))/g)
current result:
["parent( child( child_of_child(value) ) )"]
expected result:
parent: {
m: 'parent( child( child_of_child(value) ) )',
child: {
m: 'child( child_of_child(value) )',
child: {
m: 'child_of_child(value)'
}
}
}
Any help of direction will be very welcome
Upvotes: 1
Views: 919
Reputation: 163477
You might use a recursive function and a pattern with 4 capturing groups where you would match from an opening till a closing parenthesis.
Then check in the next iteration check if the pattern still matches. In the next call use the groups to construct the object with the key and the values.
([^()]+)(\()(.*)(\))
([^()]+)
Group 1, capture 1+ times not (
or )
(\()
Group 2, capture (
(.*)
Group 3, capture any char 0+ times except a newline(\))
Group 4, capture )
let pattern = /([^()]+)(\()(.*)(\))/;
let string = "parent( child( child_of_child(value) ) )";
function parse(str, obj) {
if (pattern.test(str)) {
let res = str.match(pattern);
res.shift();
parse(res[2], obj[res[0]] = {
'm': res.join('')
});
}
return obj;
}
console.log(JSON.stringify(parse(string, {}), null, 2));
Upvotes: 1
Reputation: 683
Thanks to farvilain direction, I came up with the solution for this.
the regex changed to:
/([a-z\_]+)\((.*)\)/
and istead of "match" I used "replace"
and here it goes:
var explore_parent_child = (val, reg) => {
var v = val.replace(reg, (a, b, c) => {
var res = {};
var exp = explore_parent_child(c, reg);
if(typeof(exp) == 'object') {
exp.m = a;
res[b] = exp;
} else{
res[b] = {
m: a,
child: exp
};
}
return JSON.stringify(res);
})
try { return JSON.parse(v) } catch { return v };}
example run:
explore_parent_child("parent( child( child_of_child(value) ) )", /([a-z\_]+)\((.*)\)/)
result:
parent: {
m: 'parent( child( child_of_child(value) ) )',
child: {
m: 'child( child_of_child(value) )',
child_of_child: {
m: 'child_of_child(value)',
value: 'value'
}
} }
Upvotes: 0
Reputation: 2562
Try to use this regexp instead
let regexp = /([a-z]+)(\(.*\))/;
let text = 'parent( child( child_of_child(value) ) )';
let match = text.match(regex);
Will produce
0: "parent( child( child_of_child(value) ) )"
1: "parent"
2: "( child( child_of_child(value) ) )"
The difference between our regexps are the parentheses used for capture group.
This is not exactly the output you want but the transformation will be really easy.
Upvotes: 1