在JavaScript字符串中替换最后一个匹配项

替换字符串中第一个匹配项很容易,但是如果你想要替换最后一个匹配项呢?这有点棘手,特别是如果你想要匹配String.prototype.replace()的功能。

首先,我们需要确定pattern是一个字符串还是正则表达式。如果它是一个字符串,我们可以将其作为match使用。

如果它是一个正则表达式,我们需要使用RegExp()构造函数和patternRegExp.prototype.source创建一个新的正则表达式,同时添加'g'标志。然后,我们可以使用String.prototype.match()Array.prototype.slice()来获取最后一个匹配项(如果有的话)。

然后,我们可以使用String.prototype.lastIndexOf()来找到字符串中最后一个匹配项的位置。如果找到了匹配项,我们可以使用String.prototype.slice()和模板字符串来用给定的replacement替换匹配的子字符串。如果没有找到匹配项,我们可以简单地返回原始字符串。

将所有这些组合在一起,就得到了一个灵活的实现,可以处理字符串和正则表达式,并且与String.prototype.replace()的功能相匹配:

const replaceLast = (str, pattern, replacement) => {
  const match =
    typeof pattern === 'string'
      ? pattern
      : (str.match(new RegExp(pattern.source, 'g')) || []).slice(-1)[0];
  if (!match) return str;
  const last = str.lastIndexOf(match);
  return last !== -1
    ? `${str.slice(0, last)}${replacement}${str.slice(last + match.length)}`
    : str;
};

replaceLast('abcabdef', 'ab', 'gg'); // 'abcggdef'
replaceLast('abcabdef', /ab/, 'gg'); // 'abcggdef'
replaceLast('abcabdef', 'ad', 'gg'); // 'abcabdef'
replaceLast('abcabdef', /ad/, 'gg'); // 'abcabdef'