_regexp-exec.js 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. 'use strict';
  2. var regexpFlags = require('./_flags');
  3. var nativeExec = RegExp.prototype.exec;
  4. // This always refers to the native implementation, because the
  5. // String#replace polyfill uses ./fix-regexp-well-known-symbol-logic.js,
  6. // which loads this file before patching the method.
  7. var nativeReplace = String.prototype.replace;
  8. var patchedExec = nativeExec;
  9. var LAST_INDEX = 'lastIndex';
  10. var UPDATES_LAST_INDEX_WRONG = (function () {
  11. var re1 = /a/,
  12. re2 = /b*/g;
  13. nativeExec.call(re1, 'a');
  14. nativeExec.call(re2, 'a');
  15. return re1[LAST_INDEX] !== 0 || re2[LAST_INDEX] !== 0;
  16. })();
  17. // nonparticipating capturing group, copied from es5-shim's String#split patch.
  18. var NPCG_INCLUDED = /()??/.exec('')[1] !== undefined;
  19. var PATCH = UPDATES_LAST_INDEX_WRONG || NPCG_INCLUDED;
  20. if (PATCH) {
  21. patchedExec = function exec(str) {
  22. var re = this;
  23. var lastIndex, reCopy, match, i;
  24. if (NPCG_INCLUDED) {
  25. reCopy = new RegExp('^' + re.source + '$(?!\\s)', regexpFlags.call(re));
  26. }
  27. if (UPDATES_LAST_INDEX_WRONG) lastIndex = re[LAST_INDEX];
  28. match = nativeExec.call(re, str);
  29. if (UPDATES_LAST_INDEX_WRONG && match) {
  30. re[LAST_INDEX] = re.global ? match.index + match[0].length : lastIndex;
  31. }
  32. if (NPCG_INCLUDED && match && match.length > 1) {
  33. // Fix browsers whose `exec` methods don't consistently return `undefined`
  34. // for NPCG, like IE8. NOTE: This doesn' work for /(.?)?/
  35. // eslint-disable-next-line no-loop-func
  36. nativeReplace.call(match[0], reCopy, function () {
  37. for (i = 1; i < arguments.length - 2; i++) {
  38. if (arguments[i] === undefined) match[i] = undefined;
  39. }
  40. });
  41. }
  42. return match;
  43. };
  44. }
  45. module.exports = patchedExec;