Заменить текст, но сохранить дело
У меня есть набор строк, которые мне нужно заменить, но мне нужно сохранить регистр букв. как входные слова, так и выходные слова имеют одинаковую длину.
Например, если мне нужно заменить "abcd" на "qwer", то должно произойти следующее:
"AbcD" translates to "QweR"
"abCd" translates to "qwEr"
и т.д.
Сейчас я использую JavaScript replace
, но заглавные буквы теряются при переводе.
r = new RegExp( "(" + 'asdf' + ")" , 'gi' );
"oooAsdFoooo".replace(r, "qwer");
Любая помощь будет оценена по достоинству.
Ответы
Ответ 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
:
- Мы превращаем шаблон ввода в регулярное выражение
- У нас есть вложенная функция заменителя, которая перебирает каждый символ
- Мы используем регулярное выражение
/[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