diff --git a/lib/parse.js b/lib/parse.js index 549de82e..a68f22f8 100644 --- a/lib/parse.js +++ b/lib/parse.js @@ -214,6 +214,31 @@ var parseObject = function (chain, val, options, valuesParsed) { return leaf; }; +var findSegment = function findSegment(key, start) { + var index = key.indexOf('[', start); + if (index === -1) { + return null; + } + + var depth = 0; + for (var i = index; i < key.length; ++i) { + var currentChar = key.charAt(i); + if (currentChar === '[') { + depth += 1; + } else if (currentChar === ']') { + depth -= 1; + if (depth === 0) { + return { + index: index, + text: key.slice(index, i + 1) + }; + } + } + } + + return null; +}; + var splitKeyIntoSegments = function splitKeyIntoSegments(givenKey, options) { var key = options.allowDots ? givenKey.replace(/\.([^.[]+)/g, '[$1]') : givenKey; @@ -227,10 +252,15 @@ var splitKeyIntoSegments = function splitKeyIntoSegments(givenKey, options) { return [key]; } - var brackets = /(\[[^[\]]*])/; - var child = /(\[[^[\]]*])/g; + var segment = findSegment(key, 0); + var firstBracket = key.indexOf('['); + if (!segment && firstBracket > 0 && key.indexOf(']', firstBracket) > -1) { + segment = { + index: firstBracket, + text: key.slice(firstBracket) + }; + } - var segment = brackets.exec(key); var parent = segment ? key.slice(0, segment.index) : key; var keys = []; @@ -246,17 +276,20 @@ var splitKeyIntoSegments = function splitKeyIntoSegments(givenKey, options) { } var i = 0; - while ((segment = child.exec(key)) !== null && i < options.depth) { + while (segment && i < options.depth) { i += 1; - var segmentContent = segment[1].slice(1, -1); + var isBracketedSegment = segment.text.charAt(0) === '[' + && segment.text.charAt(segment.text.length - 1) === ']'; + var segmentContent = isBracketedSegment ? segment.text.slice(1, -1) : segment.text; if (!options.plainObjects && has.call(Object.prototype, segmentContent)) { if (!options.allowPrototypes) { return; } } - keys[keys.length] = segment[1]; + keys[keys.length] = segment.text; + segment = findSegment(key, segment.index + segment.text.length); } if (segment) {