MCPcopy Create free account
hub / github.com/Rich-Harris/magic-string / _replaceRegexp

Method _replaceRegexp

src/MagicString.ts:1206–1262  ·  view source on GitHub ↗

@internal

(searchValue: RegExp, replacement: string | ReplacementFunction)

Source from the content-addressed store, hash-verified

1204
1205 /** @internal */
1206 _replaceRegexp(searchValue: RegExp, replacement: string | ReplacementFunction): this {
1207 function getReplacement(match: RegExpMatchArray, str: string): string {
1208 if (typeof replacement === 'string') {
1209 return replacement.replace(/\$(\$|&|\d+)/g, (_: string, i: string) => {
1210 // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace#specifying_a_string_as_a_parameter
1211 if (i === '$')
1212 return '$'
1213 if (i === '&')
1214 return match[0]
1215 const num = +i
1216 if (num < match.length)
1217 return match[+i]
1218 return `$${i}`
1219 })
1220 }
1221 else {
1222 return replacement(match[0], ...match.slice(1), match.index, str, match.groups)
1223 }
1224 }
1225 const replaceMatch = (match: RegExpMatchArray): void => {
1226 if (match.index == null)
1227 return
1228
1229 const replacement = getReplacement(match, this.original)
1230 if (replacement === match[0])
1231 return
1232
1233 if (match[0].length === 0) {
1234 // a zero-length match spans no characters, so there is no range to
1235 // overwrite - the replacement is an insertion at the matched position,
1236 // which is what `String.prototype.replace` does for an empty match
1237 this.appendRight(match.index, replacement)
1238 }
1239 else {
1240 this.overwrite(match.index, match.index + match[0].length, replacement)
1241 }
1242 }
1243
1244 if (searchValue.global) {
1245 // `String.prototype.replace` starts a global regexp from the beginning of
1246 // the string, so reset `lastIndex` - a regexp that has already been used
1247 // would otherwise resume from wherever it stopped and skip earlier matches.
1248 // `matchAll` also steps over a zero-length match, where `exec` in a loop
1249 // would keep rematching it at an unmoving `lastIndex` and never terminate.
1250 searchValue.lastIndex = 0
1251 for (const match of this.original.matchAll(searchValue)) {
1252 replaceMatch(match)
1253 }
1254 }
1255 else {
1256 const match = this.original.match(searchValue)
1257 if (match) {
1258 replaceMatch(match)
1259 }
1260 }
1261 return this
1262 }
1263

Callers 2

replaceMethod · 0.95
replaceAllMethod · 0.95

Calls 1

matchAllMethod · 0.80

Tested by

no test coverage detected