Reputation: 1549
I want to parse a string which contains shortcodes and push each extracted node into an array. However the recursive function I have written for this never terminates. What am I doing wrong here?
var i = 0;
var nodes = [];
var pattern = /(\[sc_(\w+)[\s\w="_-]*\])(.*)(\[\/sc_\2\])/gi;
var extractNodes = function(str, parent) {
var m;
if (str.indexOf('[sc_') === -1) return;
while ((m = pattern.exec(str)) !== null) {
nodes.push({
id: i,
tag: m[2],
children: m[3],
parentId: parent
});
extractNodes(m[3], i++);
}
}
extractNodes("[sc_div][sc_span][sc_strong]Foo[/sc_strong][/sc_span][/sc_div]", -1);
Upvotes: 1
Views: 162
Reputation: 2815
You've got a conflict between your while loop and the global (g
flag) RegEx.
Each iteration of the function is sending the same str
parameter. You can fix this by making the RegEx non-global by removing the g
flag and while
loop.
var i = 0;
var nodes = [];
var pattern = /(\[sc_(\w+)[\s\w="_-]*\])(.*)(\[\/sc_\2\])/i; // <-- Remove `g` flag
var extractNodes = function (str, parent) {
var m;
if (str.indexOf('[sc_') === -1) return;
if ((m = pattern.exec(str)) !== null) {
nodes.push({
id: i,
tag: m[2],
children: m[3],
parentId: parent
});
extractNodes(m[3], i++);
}
}
extractNodes("[sc_div][sc_span][sc_strong]Foo[/sc_strong][/sc_span][/sc_div]", -1);
console.log(nodes);
document.body.innerHTML = '<pre>' + JSON.stringify(nodes, 0, 4) + '</pre>'; // For DEMO purpose only
Console Output (Chrome):
[Object, Object, Object]
0:Object
children: "[sc_span][sc_strong]Foo[/sc_strong][/sc_span]"
id: 0
parentId: -1
tag: "div"
__proto__: Object
1:Object
children: "[sc_strong]Foo[/sc_strong]"
id: 1
parentId: 0
tag: "span"
__proto__: Object
2:Object
children: "Foo"
id: 2
parentId: 1
tag: "strong"
__proto__: Object
length: 3
__proto__: Array[0]
Upvotes: 1