123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117 |
- 'use strict';
- /* eslint-disable regexp/no-empty-capturing-group, regexp/no-empty-group, regexp/no-lazy-ends -- testing */
- /* eslint-disable regexp/no-useless-quantifier -- testing */
- var call = require('../internals/function-call');
- var uncurryThis = require('../internals/function-uncurry-this');
- var toString = require('../internals/to-string');
- var regexpFlags = require('../internals/regexp-flags');
- var stickyHelpers = require('../internals/regexp-sticky-helpers');
- var shared = require('../internals/shared');
- var create = require('../internals/object-create');
- var getInternalState = require('../internals/internal-state').get;
- var UNSUPPORTED_DOT_ALL = require('../internals/regexp-unsupported-dot-all');
- var UNSUPPORTED_NCG = require('../internals/regexp-unsupported-ncg');
- var nativeReplace = shared('native-string-replace', String.prototype.replace);
- var nativeExec = RegExp.prototype.exec;
- var patchedExec = nativeExec;
- var charAt = uncurryThis(''.charAt);
- var indexOf = uncurryThis(''.indexOf);
- var replace = uncurryThis(''.replace);
- var stringSlice = uncurryThis(''.slice);
- var UPDATES_LAST_INDEX_WRONG = (function () {
- var re1 = /a/;
- var re2 = /b*/g;
- call(nativeExec, re1, 'a');
- call(nativeExec, re2, 'a');
- return re1.lastIndex !== 0 || re2.lastIndex !== 0;
- })();
- var UNSUPPORTED_Y = stickyHelpers.BROKEN_CARET;
- // nonparticipating capturing group, copied from es5-shim's String#split patch.
- var NPCG_INCLUDED = /()??/.exec('')[1] !== undefined;
- var PATCH = UPDATES_LAST_INDEX_WRONG || NPCG_INCLUDED || UNSUPPORTED_Y || UNSUPPORTED_DOT_ALL || UNSUPPORTED_NCG;
- if (PATCH) {
- patchedExec = function exec(string) {
- var re = this;
- var state = getInternalState(re);
- var str = toString(string);
- var raw = state.raw;
- var result, reCopy, lastIndex, match, i, object, group;
- if (raw) {
- raw.lastIndex = re.lastIndex;
- result = call(patchedExec, raw, str);
- re.lastIndex = raw.lastIndex;
- return result;
- }
- var groups = state.groups;
- var sticky = UNSUPPORTED_Y && re.sticky;
- var flags = call(regexpFlags, re);
- var source = re.source;
- var charsAdded = 0;
- var strCopy = str;
- if (sticky) {
- flags = replace(flags, 'y', '');
- if (indexOf(flags, 'g') === -1) {
- flags += 'g';
- }
- strCopy = stringSlice(str, re.lastIndex);
- // Support anchored sticky behavior.
- if (re.lastIndex > 0 && (!re.multiline || re.multiline && charAt(str, re.lastIndex - 1) !== '\n')) {
- source = '(?: ' + source + ')';
- strCopy = ' ' + strCopy;
- charsAdded++;
- }
- // ^(? + rx + ) is needed, in combination with some str slicing, to
- // simulate the 'y' flag.
- reCopy = new RegExp('^(?:' + source + ')', flags);
- }
- if (NPCG_INCLUDED) {
- reCopy = new RegExp('^' + source + '$(?!\\s)', flags);
- }
- if (UPDATES_LAST_INDEX_WRONG) lastIndex = re.lastIndex;
- match = call(nativeExec, sticky ? reCopy : re, strCopy);
- if (sticky) {
- if (match) {
- match.input = stringSlice(match.input, charsAdded);
- match[0] = stringSlice(match[0], charsAdded);
- match.index = re.lastIndex;
- re.lastIndex += match[0].length;
- } else re.lastIndex = 0;
- } else if (UPDATES_LAST_INDEX_WRONG && match) {
- re.lastIndex = re.global ? match.index + match[0].length : lastIndex;
- }
- if (NPCG_INCLUDED && match && match.length > 1) {
- // Fix browsers whose `exec` methods don't consistently return `undefined`
- // for NPCG, like IE8. NOTE: This doesn't work for /(.?)?/
- call(nativeReplace, match[0], reCopy, function () {
- for (i = 1; i < arguments.length - 2; i++) {
- if (arguments[i] === undefined) match[i] = undefined;
- }
- });
- }
- if (match && groups) {
- match.groups = object = create(null);
- for (i = 0; i < groups.length; i++) {
- group = groups[i];
- object[group[0]] = match[group[1]];
- }
- }
- return match;
- };
- }
- module.exports = patchedExec;
|