1 | 'use strict';
|
---|
2 | /* eslint-disable regexp/no-assertion-capturing-group, regexp/no-empty-group, regexp/no-lazy-ends -- testing */
|
---|
3 | /* eslint-disable regexp/no-useless-quantifier -- testing */
|
---|
4 | var toString = require('../internals/to-string');
|
---|
5 | var regexpFlags = require('../internals/regexp-flags');
|
---|
6 | var stickyHelpers = require('../internals/regexp-sticky-helpers');
|
---|
7 | var shared = require('../internals/shared');
|
---|
8 | var create = require('../internals/object-create');
|
---|
9 | var getInternalState = require('../internals/internal-state').get;
|
---|
10 | var UNSUPPORTED_DOT_ALL = require('../internals/regexp-unsupported-dot-all');
|
---|
11 | var UNSUPPORTED_NCG = require('../internals/regexp-unsupported-ncg');
|
---|
12 |
|
---|
13 | var nativeExec = RegExp.prototype.exec;
|
---|
14 | var nativeReplace = shared('native-string-replace', String.prototype.replace);
|
---|
15 |
|
---|
16 | var patchedExec = nativeExec;
|
---|
17 |
|
---|
18 | var UPDATES_LAST_INDEX_WRONG = (function () {
|
---|
19 | var re1 = /a/;
|
---|
20 | var re2 = /b*/g;
|
---|
21 | nativeExec.call(re1, 'a');
|
---|
22 | nativeExec.call(re2, 'a');
|
---|
23 | return re1.lastIndex !== 0 || re2.lastIndex !== 0;
|
---|
24 | })();
|
---|
25 |
|
---|
26 | var UNSUPPORTED_Y = stickyHelpers.UNSUPPORTED_Y || stickyHelpers.BROKEN_CARET;
|
---|
27 |
|
---|
28 | // nonparticipating capturing group, copied from es5-shim's String#split patch.
|
---|
29 | var NPCG_INCLUDED = /()??/.exec('')[1] !== undefined;
|
---|
30 |
|
---|
31 | var PATCH = UPDATES_LAST_INDEX_WRONG || NPCG_INCLUDED || UNSUPPORTED_Y || UNSUPPORTED_DOT_ALL || UNSUPPORTED_NCG;
|
---|
32 |
|
---|
33 | if (PATCH) {
|
---|
34 | // eslint-disable-next-line max-statements -- TODO
|
---|
35 | patchedExec = function exec(string) {
|
---|
36 | var re = this;
|
---|
37 | var state = getInternalState(re);
|
---|
38 | var str = toString(string);
|
---|
39 | var raw = state.raw;
|
---|
40 | var result, reCopy, lastIndex, match, i, object, group;
|
---|
41 |
|
---|
42 | if (raw) {
|
---|
43 | raw.lastIndex = re.lastIndex;
|
---|
44 | result = patchedExec.call(raw, str);
|
---|
45 | re.lastIndex = raw.lastIndex;
|
---|
46 | return result;
|
---|
47 | }
|
---|
48 |
|
---|
49 | var groups = state.groups;
|
---|
50 | var sticky = UNSUPPORTED_Y && re.sticky;
|
---|
51 | var flags = regexpFlags.call(re);
|
---|
52 | var source = re.source;
|
---|
53 | var charsAdded = 0;
|
---|
54 | var strCopy = str;
|
---|
55 |
|
---|
56 | if (sticky) {
|
---|
57 | flags = flags.replace('y', '');
|
---|
58 | if (flags.indexOf('g') === -1) {
|
---|
59 | flags += 'g';
|
---|
60 | }
|
---|
61 |
|
---|
62 | strCopy = str.slice(re.lastIndex);
|
---|
63 | // Support anchored sticky behavior.
|
---|
64 | if (re.lastIndex > 0 && (!re.multiline || re.multiline && str.charAt(re.lastIndex - 1) !== '\n')) {
|
---|
65 | source = '(?: ' + source + ')';
|
---|
66 | strCopy = ' ' + strCopy;
|
---|
67 | charsAdded++;
|
---|
68 | }
|
---|
69 | // ^(? + rx + ) is needed, in combination with some str slicing, to
|
---|
70 | // simulate the 'y' flag.
|
---|
71 | reCopy = new RegExp('^(?:' + source + ')', flags);
|
---|
72 | }
|
---|
73 |
|
---|
74 | if (NPCG_INCLUDED) {
|
---|
75 | reCopy = new RegExp('^' + source + '$(?!\\s)', flags);
|
---|
76 | }
|
---|
77 | if (UPDATES_LAST_INDEX_WRONG) lastIndex = re.lastIndex;
|
---|
78 |
|
---|
79 | match = nativeExec.call(sticky ? reCopy : re, strCopy);
|
---|
80 |
|
---|
81 | if (sticky) {
|
---|
82 | if (match) {
|
---|
83 | match.input = match.input.slice(charsAdded);
|
---|
84 | match[0] = match[0].slice(charsAdded);
|
---|
85 | match.index = re.lastIndex;
|
---|
86 | re.lastIndex += match[0].length;
|
---|
87 | } else re.lastIndex = 0;
|
---|
88 | } else if (UPDATES_LAST_INDEX_WRONG && match) {
|
---|
89 | re.lastIndex = re.global ? match.index + match[0].length : lastIndex;
|
---|
90 | }
|
---|
91 | if (NPCG_INCLUDED && match && match.length > 1) {
|
---|
92 | // Fix browsers whose `exec` methods don't consistently return `undefined`
|
---|
93 | // for NPCG, like IE8. NOTE: This doesn' work for /(.?)?/
|
---|
94 | nativeReplace.call(match[0], reCopy, function () {
|
---|
95 | for (i = 1; i < arguments.length - 2; i++) {
|
---|
96 | if (arguments[i] === undefined) match[i] = undefined;
|
---|
97 | }
|
---|
98 | });
|
---|
99 | }
|
---|
100 |
|
---|
101 | if (match && groups) {
|
---|
102 | match.groups = object = create(null);
|
---|
103 | for (i = 0; i < groups.length; i++) {
|
---|
104 | group = groups[i];
|
---|
105 | object[group[0]] = match[group[1]];
|
---|
106 | }
|
---|
107 | }
|
---|
108 |
|
---|
109 | return match;
|
---|
110 | };
|
---|
111 | }
|
---|
112 |
|
---|
113 | module.exports = patchedExec;
|
---|