Как заменить все вхождения строки, кроме первого в JavaScript?

у меня есть эта строка:

hello world hello world hello world hello

и мне нужно сделать следующее:

hello world hello hello hello

если я использую:

str = str.replace('world', '');

Он удаляет только первое вхождение world в строке выше.

как я могу заменить все вхождения, кроме первого?

5 ответов


вы можете передать функцию строка#replace, где вы можете указать, чтобы опустить замену первого вхождения. Также сделайте свой первый параметр заменить регулярное выражение, соответствующее всем вхождениям.

демо

let str = 'hello world hello world hello world hello',
    i = 0;
    
str = str.replace(/world/g, m  => !i++ ? m : '');
console.log(str);

Примечание

вы можете избежать использования глобальной переменной счетчика i С помощью жизнь:

let str = 'hello world hello world hello world hello';

str = str.replace(/world/g, (i => m => !i++ ? m : '')(0));
console.log(str);

чтобы предоставить альтернативу @Kristianmitk отличный ответ, мы можем использовать положительный lookbehind, который поддерживается в узел.Js & Chrome > = 62

const string = 'hello world hello world hello world hello';

console.log(
  string.replace(/(?<=world[\s\S]+)world/g, '')
);
// or
console.log(
  string.replace(/(?<=(world)[\s\S]+)/g, '')
);

используя символ.заменить известный символ.

Символ.replace известный символ указывает метод, который заменяет совпадающие подстроки строки. Эта функция вызывается строка.прототип.заменять() метод.

const string = 'hello world hello world hello world hello';

class ReplaceButFirst {
     constructor(word, replace = '') {
         this.count = 0;
         this.replace = replace;
         this.pattern = new RegExp(word, 'g');
     }
     
     [Symbol.replace](str) {
          return str.replace(this.pattern, m => !this.count++ ? m : this.replace);
     }
}

console.log(
  string.replace(new ReplaceButFirst('world'))
);

var str = 'hello world hello world hello world hello'; 

var count = 0;
var result = str.replace(/world/gi, function (x) {
  if(count == 0) {
      count++;
      return x;
    } else {
      return '';	
    }
});

console.log(result);

в моем решении я заменяю первое вхождение текущей меткой времени, затем заменяю все вхождения, а затем, наконец, заменяю метку времени на world

вы также можете использовать str.split('world') и затем присоединиться

var str = 'hello world hello world hello world hello';
var strs = str.split('world');
str = strs[0] + 'world' + strs.slice(1).join('');
console.log(str);

var str = 'hello world hello world hello world hello';

const d = Date.now()
str = str.replace('world', d).replace(/world/gi, '').replace(d, 'world');

console.log(str);

Я бы сделал так:

  1. получить подстроку до и включая первое вхождение.
  2. добавьте к этому подстроку после первого вхождения, при этом все остальные вхождения будут удалены:

    function replaceExceptFirst(str, search) {
         let index = str.indexOf(search);
         return str.substring(0, index + search.length) + 
             str.substring(index + search.length).replace(/world/g, '')
    }
    
    console.log(replaceExceptFirst('hello world hello world world hello', 'world'))