Spec-Zone.ru › JavaScript

RegExp.prototype[Symbol.replace]()

Базовый уровень Широко доступно

Эта функция хорошо зарекомендовала себя и работает на многих устройствах и версиях браузеров. Она доступна в браузерах с июля 2015 года.

Метод [Symbol.replace]() экземпляров RegExp определяет, как должны вести себя String.prototype.replace() и String.prototype.replaceAll() при передаче регулярного выражения в качестве шаблона.

Попробуйте

class RegExp1 extends RegExp {
  [Symbol.replace](str) {
    return RegExp.prototype[Symbol.replace].call(this, str, "#!@?");
  }
}

console.log("football".replace(new RegExp1("foo")));
// Expected output: "#!@?tball"

Синтаксис

regexp[Symbol.replace](str, replacement)

Параметры

str
Объект String, являющийся целью замены.
replacement
Может быть строкой или функцией.
  • Если это строка, она заменит подстроку, соответствующую текущему регулярному выражению. Поддерживается ряд специальных шаблонов замены; см. раздел Указание строки в качестве замены String.prototype.replace.
  • Если это функция, она будет вызываться для каждого совпадения, а возвращаемое значение будет использоваться в качестве текста замены. Аргументы, передаваемые этой функции, описаны в разделе Указание функции в качестве замены String.prototype.replace.

Возвращаемое значение

Новая строка, в которой одно, несколько или все совпадения шаблона заменены указанной заменой.

Описание

Этот метод существует для настройки поведения замены в подклассах RegExp. Он вызывается внутренне в String.prototype.replace() и String.prototype.replaceAll(), если аргумент pattern является объектом RegExp. Например, следующие два примера дают одинаковый результат.

"abc".replace(/a/, "A");

/a/[Symbol.replace]("abc", "A");

Если регулярное выражение глобальное (с флагом g), его lastIndex сначала устанавливается в 0, поэтому поиск совпадений всегда начинается с начала строки, и метод exec() регулярного выражения вызывается повторно до тех пор, пока exec() не вернет null. Если текущее совпадение является пустой строкой, lastIndex все равно будет продвигаться — если регулярное выражение учитывает Unicode, оно будет продвигаться на один Unicode-код-пойнт; в противном случае оно продвигается на одну UTF-16 кодовую единицу.

console.log("😄".replace(/(?:)/g, " ")); // " \ud83d \ude04 "
console.log("😄".replace(/(?:)/gu, " ")); // " 😄 "

Если регулярное выражение не является глобальным, exec() будет вызываться только один раз.

Замена происходит после идентификации всех совпадающих подстрок. Для каждого успешного результата exec() создается строка подстановки на основе аргумента replacement, процесс которой описан в String.prototype.replace().

Метод exec() автоматически сбрасывает lastIndex в 0, когда последнее совпадение не найдено, поэтому для глобальных регулярных выражений с lastIndex, начинающимся с 0, [Symbol.replace]() обычно не вызывает побочных эффектов. Однако, когда регулярное выражение липкое, но не глобальное, exec() вызывается только один раз и, следовательно, не сбрасывает lastIndex, если совпадение было успешным. В этом случае каждый вызов replace() может вернуть разный результат.

const re = /a/y;

for (let i = 0; i < 5; i++) {
  console.log("aaa".replace(re, "b"), re.lastIndex);
}

// baa 1
// aba 2
// aab 3
// aaa 0
// baa 1

Когда регулярное выражение является липким и глобальным, оно по-прежнему будет выполнять липкие совпадения — то есть, оно не будет находить совпадений за пределами lastIndex.

console.log("aa-a".replace(/a/gy, "b")); // "bb-a"

Примеры

Прямой вызов

Этот метод можно использовать почти так же, как String.prototype.replace(), за исключением другого this и другого порядка аргументов.

const re = /-/g;
const str = "2016-01-01";
const newStr = re[Symbol.replace](str, ".");
console.log(newStr); // 2016.01.01

Использование [Symbol.replace]() в подклассах

Подклассы RegExp могут переопределить метод [Symbol.replace]() для изменения поведения по умолчанию.

class MyRegExp extends RegExp {
  constructor(pattern, flags, count) {
    super(pattern, flags);
    this.count = count;
  }
  [Symbol.replace](str, replacement) {
    // Perform [Symbol.replace]() `count` times.
    let result = str;
    for (let i = 0; i < this.count; i++) {
      result = RegExp.prototype[Symbol.replace].call(this, result, replacement);
    }
    return result;
  }
}

const re = new MyRegExp("\\d", "", 3);
const str = "01234567";
const newStr = str.replace(re, "#"); // String.prototype.replace calls re[Symbol.replace]().
console.log(newStr); // ###34567

Спецификации

Спецификация
ECMAScript® 2027 Language Specification
# sec-regexp.prototype-%symbol.replace%

Совместимость с браузерами

Desktop Mobile Server
Chrome Edge Firefox Opera Safari Chrome Android Firefox for Android Opera Android Safari on iOS Samsung Internet WebView Android WebView on iOS Bun Deno Node.js
@@replace
50
79
49
37
10
50
49
37
10
5.0
50
10
1.0.0
1.0
6.0.0

См. также

  • Polyfill RegExp.prototype[Symbol.replace] в core-js
  • String.prototype.replace()
  • String.prototype.replaceAll()
  • RegExp.prototype[Symbol.match]()
  • RegExp.prototype[Symbol.matchAll]()
  • RegExp.prototype[Symbol.search]()
  • RegExp.prototype[Symbol.split]()
  • RegExp.prototype.exec()
  • RegExp.prototype.test()
  • Symbol.replace

© 2005–2025 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/Symbol.replace

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API