diff --git a/src/util.js b/src/util.js index be06f558..c00d9c51 100644 --- a/src/util.js +++ b/src/util.js @@ -161,18 +161,22 @@ export function createRegExpRestore () { let m = regExpCache['$'+i]; // If it's empty, add an empty capturing group - if (!m) - lm = '()' + lm; - + if (!m) { + arrPush.call(reg, '('); + lm = ')' + lm; + } // Else find the string in lm and escape & wrap it to capture it else { m = m.replace(esc, '\\$&'); - lm = lm.replace(m, '(' + m + ')'); + let [ left, ...right ] = lm.split(m); + left += '('; + lm = m + ')' + right.join(''); + // Push it to the reg and chop lm to make sure further groups come after + arrPush.call(reg, left); } - // Push it to the reg and chop lm to make sure further groups come after - arrPush.call(reg, lm.slice(0, lm.indexOf('(') + 1)); - lm = lm.slice(lm.indexOf('(') + 1); + + } } @@ -183,8 +187,9 @@ export function createRegExpRestore () { // expressions generated above, because the expression matches the whole // match string, so we know each group and each segment between capturing // groups can be matched by its length alone. - exprStr = exprStr.replace(/(\\\(|\\\)|[^()])+/g, (match) => { - return `[\\s\\S]{${match.replace('\\','').length}}`; + // exprStr = exprStr.replace(/([^\\]\\\(|[^\\]\\\)|[^()])+/g, (match) => { + exprStr = exprStr.replace(/([^\\](\\\\)*\\[\)\(]((\\\\)*\\[\(\)])*|[^()])+/g, (match) => { + return `[\\s\\S]{${match.replace(/\\(.)/g, '$1').length}}`; }); // Create the regular expression that will reconstruct the RegExp properties diff --git a/tests/disableregexprestore.js b/tests/disableregexprestore.js index 497fed7d..d7f04edc 100644 --- a/tests/disableregexprestore.js +++ b/tests/disableregexprestore.js @@ -29,6 +29,16 @@ new IntlPolyfill.NumberFormat('en-US', { assertEqual(RegExp.input, 'a foo test', 'Normally, RegExp.input should be cached and restored'); assertEqual(RegExp.lastMatch, 'foo', 'Normally, RegExp.lastMatch should be cached and restored'); +// Issues #231 +/function[\s\S]+(})/.exec('function defineProperty\\(\\) \\{\n \\[native code\\]\n\\}'); +new IntlPolyfill.NumberFormat('en-US', { + style: 'currency', + currency: 'GBP', + minimumFractionDigits: 2, +}); +assertEqual(RegExp.input, 'function defineProperty\\(\\) \\{\n \\[native code\\]\n\\}', 'Normally, RegExp.input should be cached and restored'); +assertEqual(RegExp.lastMatch, 'function defineProperty\\(\\) \\{\n \\[native code\\]\n\\}', 'Normally, RegExp.lastMatch should be cached and restored'); + IntlPolyfill.__disableRegExpRestore(); /foo/.exec('a foo test'); new IntlPolyfill.NumberFormat('en-US', {