我有一组需要替换的字符串,但我需要保留字母的大小写。
输入字和输出字的长度相同。
例如,如果我需要将"abcd"替换为"qwer",则应发生以下情况:
"AbcD" translates to "QweR"
"abCd" translates to "qwEr"
等等。
现在我正在使用JavaScript的replace
,但是大写字母在翻译时丢失了。
r = new RegExp( "(" + 'asdf' + ")" , 'gi' );
"oooAsdFoooo".replace(r, "qwer");
任何帮助将不胜感激。
下面是一个帮助程序:
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);
});
我将把这个留在这里供参考。
场景:项目列表上的搜索框不区分大小写,字符串上的部分匹配应突出显示,但保留原始大小写。
highlight() {
const re = new RegExp(this.searchValue, 'gi'); // global, insensitive
const newText = name.replace(re, `<b>$&</b>`);
return newText;
}
$&是带大小写的匹配文本
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"
下面是一个replaceCase
函数:
- 我们将输入模式转换为正则表达式
- 我们有一个嵌套的替换函数,它遍历每个字符
- 我们使用正则表达式
/[A-Z]/
来识别大写字母,否则我们假设所有内容都是小写的
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
您可以创建自己的替换函数,例如
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);
这意味着如果需要,您可以使用不同的映射传递不同的对象。这是一个显示示例的简单小提琴(请注意,对象都是小写的,但函数本身也会查看字符串的大小写(
扩展Ryan O'Hara的答案,以下解决方案避免使用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);
}
这应该在保留大小写的同时替换。如果有人在此解决方案中发现任何缺陷,请告诉我。我希望这有所帮助。谢谢!
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");
我有一个句子,我必须用另一个单词替换每个单词,并且该单词可以比它替换的单词长/短,因此它类似于问题,但不是固定长度,它们是动态的。
我的解决方案
为简单起见,我只关注一个词。
const oldWord = "tEsT";
const newWord = "testing";
拆分这两个单词,以便我可以遍历每个单独的字母。
const oldWordLetters = oldWord.split("");
const newWordLetters = newWord.split("");
现在,我将遍历newWord
字母并使用其索引将相应的oldWord
字母放在相同的位置。然后我会检查旧字母是否大写,如果是,那么新字母也在同一位置大写。
for (const [i, letter] of newWordLetters.entries()) {
const oldLetter = oldWordLetters[i];
// stop iterating if oldWord is shorter (not enough letters to copy case).
if (!oldLetter) {
break;
}
const isCapital = oldLetter === oldLetter.toUpperCase();
// make the new letter in the same position as the old letter capital
if (isCapital) {
newWordLetters[i] = letter.toUpperCase();
}
}
最终的世界将在再次加入字母后tEsTing
。
const finalWord = newWordLetters.join("");
console.log(finalWord); // "tEsTing"
完整代码
const oldWord = "tEsT";
const newWord = "testing";
const oldWordLetters = oldWord.split("");
const newWordLetters = newWord.split("");
for (const [i, letter] of newWordLetters.entries()) {
const oldLetter = oldWordLetters[i];
// stop iterating if oldWord is shorter (not enough letters to copy case).
if (!oldLetter) {
break;
}
const isCapital = oldLetter === oldLetter.toUpperCase();
// make the new letter in the same position as the old letter capital
if (isCapital) {
newWordLetters[i] = letter.toUpperCase();
}
}
const finalWord = newWordLetters.join("");
console.log(finalWord);
我认为这可以工作
function formatItem(text, searchText){
const search = new RegExp(escapeRegExp(searchText), 'iu')
return text?.toString().replace(search, (m) => `<b>${m}</b>`)
}
function escapeRegExp(text) {
return text?.replace(/[-[]{}()*+?.,\^$|#s]/g, '\$&') ?? '';
}
谢谢你问这个问题。 当我想搜索文本并用链接替换某些单词时,我遇到了同样的问题,这是一个稍微更具体的情况,因为它正在用 html 字符串替换文本字符串。 我会把我的解决方案放在这里,以防任何发现它的人正在做类似的事情。
let elmt = document.getElementById('the-element');
let a = document.createElement('a');
a.href = "https://www.example.com";
let re = new RegExp('the string to find', 'gi');
elmt.innerHTML = elmt.innerHTML.replaceAll(re, function (match) {
a.innerText = match;
return a.outerHTML;
});
因此,正则表达式确保它搜索不区分大小写的匹配项,并且作为 replaceAll 函数的第二个参数的函数指定它应该将新标签的 innerText 设置为逐字旧字符串相等,然后返回整个标签的 outerHTML。
replaceAllCaseSensitive
函数。如果需要,可以通过replace
更改replaceAll
。
const replaceAllCaseSensitive = (
text, // Original string
pattern, // RegExp with the pattern you want match. It must include the g (global) and i (case-insensitive) flags.
replacement // string with the replacement
) => {
return text.replaceAll(pattern, (match) => {
return replacement
.split("")
.map((char, i) =>
match[i] === match[i].toUpperCase() ? char.toUpperCase() : char
)
.join("");
});
};
console.log(replaceAllCaseSensitive("AbcD abCd", /abcd/gi, "qwer"));
// outputs "QweR qwEr"
console.log(replaceAllCaseSensitive("AbcD abCd", /abcd/gi, "qwe"));
// outputs "Qwe qwE"
即使replacement
短于 match
,该函数也有效。
我真的很喜欢 Stephen Quan 的答案,但发现它无法处理替换字符串与匹配字符串长度不同的情况。这是我对他的回答的更新
const replaceCase = (str, pattern, newStr) => {
const rx = new RegExp(pattern, 'ig');
const replacer = (c, i) => (c.match(/[A-Z]/) ? newStr[i].toUpperCase() : newStr[i] ?? '');
const [match] = str.match(rx) ?? [];
return str.replace(rx, (oldStr) => oldStr.replace(/./g, replacer)) + newStr.slice(match?.length ?? 0);
};
在TypeScript中为那些喜欢的人
const replaceCase = (str: string, pattern: RegExp, newStr: string) => {
const rx = new RegExp(pattern, 'ig');
const replacer = (c: string, i: number) =>
c.match(/[A-Z]/) ? newStr[i].toUpperCase() : newStr[i] ?? '';
const [match] = str.match(rx) ?? [];
return (
str.replace(rx, (oldStr) => oldStr.replace(/./g, replacer)) + newStr.slice(match?.length ?? 0)
);
};