Для простых случаев, когда заменой является строка, для второго аргумента .replace
используйте функцию обратного вызова, а не простую строку replacement
, и сделайте так, чтобы обратный вызов увеличил переменную:
function countReplacements(string, search, replacement) {
let count = 0;
const result = string.replace(search, () => {
count++;
return replacement;
});
return { count, result };
}
console.log(countReplacements('foobar', /o/g, 'a'));
Для более сложных случаев, когда replacement
является функцией или строкой, содержащей ссылки на группы, вам придется либо заново реализовать String.prototype.replace
самостоятельно:используйте параметры, предоставленные для .replace
, чтобы получить полное совпадение и группы:
function countReplacements(string, search, replacement) {
let count = 0;
const result = string.replace(search, (match, ...groups) => {
count++;
return replacement
.replace(/\$(\d+|&)/g, (_, indicator) => {
if (indicator === '&') return match;
if (/^\d+$/.test(indicator)) return groups[indicator - 1];
// and so on for other `$`s
});
});
return { count, result };
}
console.log(countReplacements ( 'foobar', /(o)/g, '$1_' ));
Гораздо более ленивая, но более простая в реализации версия - просто вызвать match
и проверить length
результата, хотя для этого потребуется пройти строку срегулярное выражение дважды :
function countReplacements(string, search, replacement) {
const match = string.match(search);
const count = match ? match.length : 0;
const result = string.replace(search, replacement);
return { count, result };
}
console.log(countReplacements ( 'foobar', /(o)/g, '$1_' ));
Если поиск является строкой или неглобальным регулярным выражением, я могу проверить, содержит ли строка / соответствует ли она.Но если поиск является глобальным регулярным выражением, когда JS будет иметь поддержку lookbehinds, я не уверен, что это сработает, может быть, все совпадения вычисляются до их фактической замены?Если это не так, любая замена может привести к тому, что приведенные ниже взгляды больше не будут совпадать или теперь будут совпадать с вещами, которые не соответствовали бы в исходной строке.
Это не будетпроблема - единственная проблема с использованием .match
для получения счетчика в дополнение к .replace
заключается в том, что для этого требуется дважды пройти строку.Все замещения строки рассчитываются сразу, где обходные пути смотрят на исходную строку .Затем, когда все совпадения найдены и замены рассчитаны, каждая подходящая подстрока заменяется своей заменой.