Заменить текст, но сохранить дело - программирование
Подтвердить что ты не робот

Заменить текст, но сохранить дело

У меня есть набор строк, которые мне нужно заменить, но мне нужно сохранить регистр букв. как входные слова, так и выходные слова имеют одинаковую длину.

Например, если мне нужно заменить "abcd" на "qwer", то должно произойти следующее:

"AbcD" translates to "QweR"
"abCd" translates to "qwEr"

и т.д.

Сейчас я использую JavaScript replace, но заглавные буквы теряются при переводе.

r = new RegExp( "(" + 'asdf' + ")" , 'gi' );
"oooAsdFoooo".replace(r, "qwer");

Любая помощь будет оценена по достоинству.

4b9b3361

Ответ 1

Heres a helper:

function matchCase(text, pattern) {
    var result = '';

    for(var i = 0; i < text.length; i++) {
        var c = text.charAt(i);
        var p = pattern.charCodeAt(i);

        if(p >= 65 && p < 65 + 26) {
            result += c.toUpperCase();
        } else {
            result += c.toLowerCase();
        }
    }

    return result;
}

Тогда вы можете просто:

"oooAsdFoooo".replace(r, function(match) {
    return matchCase("qwer", match);
});

Ответ 2

String.prototype.translateCaseSensitive = function (fromAlphabet, toAlphabet) {
    var fromAlphabet = fromAlphabet.toLowerCase(),
        toAlphabet = toAlphabet.toLowerCase(),
        re = new RegExp("[" + fromAlphabet + "]", "gi");

    return this.replace(re, function (char) {
        var charLower = char.toLowerCase(),
            idx = fromAlphabet.indexOf(charLower);

        if (idx > -1) {
            if (char === charLower) {
                return toAlphabet[idx];
            } else {
                return toAlphabet[idx].toUpperCase();
            }
        } else {
            return char;
        }
    });
};

и

"AbcD".translateCaseSensitive("abcdefg", "qwertyu")

вернется:

"QweR"

Ответ 3

Вы можете создать свою собственную функцию замены, например

 if(!String.prototype.myreplace){
String.prototype.myreplace = (function(obj){
    return this.replace(/[a-z]{1,1}/gi,function(a,b){
       var r = obj[a.toLowerCase()] || a;
        return a.charCodeAt(0) > 96? r.toLowerCase() : r.toUpperCase();
    });
});
}

Это принимает объект, который отображает разные буквы. и его можно назвать так:

  var obj = {a:'q',b:'t',c:'w'};

  var s = 'AbCdea';
  var n = s.myreplace(obj);
  console.log(n);

Это означает, что вы можете потенциально передавать разные объекты с помощью разных сопоставлений, если это необходимо. Вот простой пример fiddle, показывающий пример (обратите внимание, что объект имеет все строчные буквы, но сама функция также смотрит на случай строки)

Ответ 4

Это необходимо заменить, сохранив случай. Пожалуйста, дайте мне знать, найдут ли кто-либо недостатки в этом решении. Надеюсь, это поможет. Спасибо вам!

function myReplace(str, before, after) {

      var match=function(before,after){
        after=after.split('');
        for(var i=0;i<before.length;i++)
          {

            if(before.charAt(i)==before[i].toUpperCase())
              {
                after[i]=after[i].toUpperCase();
              }
            else  if(before.charAt(i)==before[i].toLowerCase())
              {
                after[i]=after[i].toLowerCase();
              }
            return after.join('');
          }

      };
           console.log(before,match(before,after));
          str =str.replace(before,match(before,after)); 


      return str;
    }

    myReplace("A quick brown fox jumped over the lazy dog", "jumped", "leaped");

Ответ 5

Развернувшись на ответ Райана О'Хара, нижеприведенное решение избегает использования charCodes и проблем, которые могут возникнуть при их использовании. Он также гарантирует, что замена будет завершена, когда строки имеют разную длину.

function enforceLength(text, pattern, result) {
  if (text.length > result.length) {  
    result = result.concat(text.substring(result.length, text.length));
  }

  if (pattern.length > text.length) {
    result = result.substring(0, text.length);
  }

  return result;
}

function matchCase(text, pattern){
  var result = '';

  for (var i =0; i < pattern.length; i++){
    var c = text.charAt(i);
    var p = pattern.charAt(i);

    if(p === p.toUpperCase()) {
       result += c.toUpperCase();
    } else {
       result += c.toLowerCase();
    }
  }  
  return enforceLength(text, pattern, result);
}

Ответ 6

Вот функция replaceCase:

  1. Мы превращаем шаблон ввода в регулярное выражение
  2. У нас есть вложенная функция заменителя, которая перебирает каждый символ
  3. Мы используем регулярное выражение /[AZ]/ для определения заглавных букв, в противном случае мы предполагаем, что все в нижнем регистре

function replaceCase(str, pattern, newStr) {
  const rx = new RegExp(pattern, "ig")
  const replacer = (c, i) => c.match(/[A-Z]/) ? newStr[i].toUpperCase() : newStr[i]
  return str.replace(rx, (oldStr) => oldStr.replace(/./g, replacer) )
}

let out = replaceCase("This is my test string: AbcD", "abcd", "qwer")
console.log(out) // This is my test string: QweR
out = replaceCase("This is my test string: abCd", "abcd", "qwer")
console.log(out) // This is my test string: qwEr