Javascript: заменить повторяющийся символ в строке?

#javascript #string #regexp-replace

#javascript #строка #регулярное выражение-заменить

Вопрос:

Я решал katas в codewars и наткнулся на общую проблему с кодом, на которую, похоже, не могу найти ответ.

Это мой код:

 function wave(str) {
   let arr = [];
   for (var i = 0; i < str.length; i  ) {
       str[i].match(/S/) amp;amp; arr.push(str.replace(str[i], str[i].toUpperCase()));
   }
   return arr;
 };

  

(Примечание: ввод всегда в нижнем регистре.)
В случае wave("abc def"); код делает именно то, что я хочу:

 ["Abc def", "aBc def", "abC def", "abc Def", "abc dEf", "abc deF"]
  

=> Функция принимает строку, вводит заглавную букву строки, начинающуюся с str[0] , вставляет новое слово в arr , увеличивает i и повторяет процесс до i < str.length , затем возвращает arr со всеми результатами.

Однако, если я введу, wave("acc def"); например, только первое вхождение буквы c будет возвращено с заглавной буквы:

 ["Acc def", "aCc def", "aCc def", "acc Def", "acc dEf", "acc deF"]
  

Вопрос: Почему он «перепрыгивает» второе вхождение ‘c’ и как я могу настроить таргетинг на второе или n-е вхождение символа в строке?

Комментарии:

1. «только первое вхождение» ~ Попробуйте глобальное сопоставление /S/g ?

2. str.replace(str[i], ...) заменит только первое вхождение символа в str[i] (следовательно, он также не будет работать с cac def )

3. возьмите часть слева от str[i] ( .slice() ), возьмите версию в верхнем регистре str[i] , возьмите часть справа от str[i] ( .slice() ) — объедините их снова

Ответ №1:

str.replace("x", "y") заменяет первое вхождение "x" в str на "y"
Если в строке есть только уникальные символы, ваш подход работает, но он не сработает, если есть дублированные символы, как в "acc def"

Вы могли бы .slice() разделить строку на три части:

  • Часть, оставшаяся от i -> .slice(0, i)
  • Символ в индексе i -> str[i]
  • Оставшаяся часть после индекса i -> .slice(i 1)

Измените str[i] по мере необходимости и объедините их обратно в одну строку с .join("")

 function wave(str) {
  const result = [];
  
  for (let i = 0; i < str.length; i  ) {
    if (!str[i].match(/S/)) continue;
    
    result.push([
                  str.slice(0, i),      /* the part left of str[i] */
                  str[i].toUpperCase(), /* str[i] */
                  str.slice(i   1)      /* the remaining part right of str[i] */
                ].join(""))  // combine the parts in the array into a string
  }
  
  return resu<
 };
 
 
 console.log(JSON.stringify(wave("abc def")));
 console.log(JSON.stringify(wave("acc def")));  

Ответ №2:

Когда вы говорите str.replace(str[i], str[i].toUpperCase()) , вы говорите: «Замените первое вхождение str[i] на str[i].toUpperCase() «, и это именно то, что делает ваша программа.

Рассмотрите возможность создания вашей новой строки следующим образом:

 str.substring(0, i)   str[i].toUpperCase()   str.substring(i 1)