1 | 'use strict';
|
2 | var fixRegExpWellKnownSymbolLogic = require('../internals/fix-regexp-well-known-symbol-logic');
|
3 | var anObject = require('../internals/an-object');
|
4 | var toObject = require('../internals/to-object');
|
5 | var toLength = require('../internals/to-length');
|
6 | var toInteger = require('../internals/to-integer');
|
7 | var requireObjectCoercible = require('../internals/require-object-coercible');
|
8 | var advanceStringIndex = require('../internals/advance-string-index');
|
9 | var regExpExec = require('../internals/regexp-exec-abstract');
|
10 |
|
11 | var max = Math.max;
|
12 | var min = Math.min;
|
13 | var floor = Math.floor;
|
14 | var SUBSTITUTION_SYMBOLS = /\$([$&'`]|\d\d?|<[^>]*>)/g;
|
15 | var SUBSTITUTION_SYMBOLS_NO_NAMED = /\$([$&'`]|\d\d?)/g;
|
16 |
|
17 | var maybeToString = function (it) {
|
18 | return it === undefined ? it : String(it);
|
19 | };
|
20 |
|
21 |
|
22 | fixRegExpWellKnownSymbolLogic('replace', 2, function (REPLACE, nativeReplace, maybeCallNative) {
|
23 | return [
|
24 |
|
25 |
|
26 | function replace(searchValue, replaceValue) {
|
27 | var O = requireObjectCoercible(this);
|
28 | var replacer = searchValue == undefined ? undefined : searchValue[REPLACE];
|
29 | return replacer !== undefined
|
30 | ? replacer.call(searchValue, O, replaceValue)
|
31 | : nativeReplace.call(String(O), searchValue, replaceValue);
|
32 | },
|
33 |
|
34 |
|
35 | function (regexp, replaceValue) {
|
36 | var res = maybeCallNative(nativeReplace, regexp, this, replaceValue);
|
37 | if (res.done) return res.value;
|
38 |
|
39 | var rx = anObject(regexp);
|
40 | var S = String(this);
|
41 |
|
42 | var functionalReplace = typeof replaceValue === 'function';
|
43 | if (!functionalReplace) replaceValue = String(replaceValue);
|
44 |
|
45 | var global = rx.global;
|
46 | if (global) {
|
47 | var fullUnicode = rx.unicode;
|
48 | rx.lastIndex = 0;
|
49 | }
|
50 | var results = [];
|
51 | while (true) {
|
52 | var result = regExpExec(rx, S);
|
53 | if (result === null) break;
|
54 |
|
55 | results.push(result);
|
56 | if (!global) break;
|
57 |
|
58 | var matchStr = String(result[0]);
|
59 | if (matchStr === '') rx.lastIndex = advanceStringIndex(S, toLength(rx.lastIndex), fullUnicode);
|
60 | }
|
61 |
|
62 | var accumulatedResult = '';
|
63 | var nextSourcePosition = 0;
|
64 | for (var i = 0; i < results.length; i++) {
|
65 | result = results[i];
|
66 |
|
67 | var matched = String(result[0]);
|
68 | var position = max(min(toInteger(result.index), S.length), 0);
|
69 | var captures = [];
|
70 |
|
71 |
|
72 |
|
73 |
|
74 |
|
75 | for (var j = 1; j < result.length; j++) captures.push(maybeToString(result[j]));
|
76 | var namedCaptures = result.groups;
|
77 | if (functionalReplace) {
|
78 | var replacerArgs = [matched].concat(captures, position, S);
|
79 | if (namedCaptures !== undefined) replacerArgs.push(namedCaptures);
|
80 | var replacement = String(replaceValue.apply(undefined, replacerArgs));
|
81 | } else {
|
82 | replacement = getSubstitution(matched, S, position, captures, namedCaptures, replaceValue);
|
83 | }
|
84 | if (position >= nextSourcePosition) {
|
85 | accumulatedResult += S.slice(nextSourcePosition, position) + replacement;
|
86 | nextSourcePosition = position + matched.length;
|
87 | }
|
88 | }
|
89 | return accumulatedResult + S.slice(nextSourcePosition);
|
90 | }
|
91 | ];
|
92 |
|
93 |
|
94 | function getSubstitution(matched, str, position, captures, namedCaptures, replacement) {
|
95 | var tailPos = position + matched.length;
|
96 | var m = captures.length;
|
97 | var symbols = SUBSTITUTION_SYMBOLS_NO_NAMED;
|
98 | if (namedCaptures !== undefined) {
|
99 | namedCaptures = toObject(namedCaptures);
|
100 | symbols = SUBSTITUTION_SYMBOLS;
|
101 | }
|
102 | return nativeReplace.call(replacement, symbols, function (match, ch) {
|
103 | var capture;
|
104 | switch (ch.charAt(0)) {
|
105 | case '$': return '$';
|
106 | case '&': return matched;
|
107 | case '`': return str.slice(0, position);
|
108 | case "'": return str.slice(tailPos);
|
109 | case '<':
|
110 | capture = namedCaptures[ch.slice(1, -1)];
|
111 | break;
|
112 | default:
|
113 | var n = +ch;
|
114 | if (n === 0) return match;
|
115 | if (n > m) {
|
116 | var f = floor(n / 10);
|
117 | if (f === 0) return match;
|
118 | if (f <= m) return captures[f - 1] === undefined ? ch.charAt(1) : captures[f - 1] + ch.charAt(1);
|
119 | return match;
|
120 | }
|
121 | capture = captures[n - 1];
|
122 | }
|
123 | return capture === undefined ? '' : capture;
|
124 | });
|
125 | }
|
126 | });
|