我想在JavaScript中使用不区分大小写的字符串replace-all而不使用正则表达式(或者在调用replace方法时使用正则表达式字符串)。我无法找到问题或答案,但如果我错过了,请将其链接。
例如,在:中用'x'替换'abc' Find aBc&def stuff ABCabc
变为Find x&def stuff xx
结果应该保留未更换部分的原始情况。
字符串中可能包含特殊字符,所以这就是为什么我要避免使用正则表达式。我的特殊问题可以通过正则表达式解决,但我有兴趣完全避免它。
有几个问题和答案使用正则表达式,并包括特殊字符的处理。特别是,bobince在这里的回答https://stackoverflow.com/a/280837/292060描述了如果不了解或采取原始字符串中的特定条件,它可能是不可能的。
我认为它将涉及循环和indexOf,并遍历原始字符串,构建结果。
为了这个问题,让我们说性能不是主要问题。例如,循环字符可以。
现有的一些问题包括所有答案的正则表达式:
修改
从一些答案,一些澄清 - 我最初没有说明这些,但它们是典型的搜索/替换行为:
可以替换为相同的字符串,例如,将'abc'替换为'Abc',比如修复名称的标题大小写。
不应重新检查替换,例如,将“ab”替换为“abc”应该有效。例如,在abcc
中将'abc'替换为'ab'会变为abc
而不是ab
。
我认为这些归结为更换应该完成,然后在字符串中移动,而不是“回头看”。
修改 以下是一些仅供记录的测试用例。我没有进入空字符串等,这可能也应该进行测试。 https://jsfiddle.net/k364st09/1/
("Find aBc&def abc", "abc", "xy") - Find xy&def xy - general test
("Find aBc&def abc", "abc", "ABC") - Find ABC&def ABC - replace same test, avoid infinite loop
("Find aBcc&def abc", "abc", "ab") - Find abc&def ab - "move on" avoid double checking (fails if abcc becomes ab)
("abc def", "abc", "xy") - xy def - Don't drop last characters.
("abcc def", "abc", "xy") - xyc def - Just a mix of "move on" and "don't drop last".
答案 0 :(得分:2)
为了好玩,我创建了一个交互式版本,您可以在其中查看正则表达式和indexOf的结果,以查看转义正则表达式是否会破坏任何内容。用于转义我从jQuery UI获取的正则表达式的方法。如果您将其包含在页面中,则可以使用$.ui.autocomplete.escapeRegex
找到它。否则,它的功能非常小。
这里是非正则表达式函数,但由于交互式部分添加了更多代码,因此我默认隐藏了完整的代码段。
function insensitiveReplaceAll(original, find, replace) {
var str = "",
remainder = original,
lowFind = find.toLowerCase(),
idx;
while ((idx = remainder.toLowerCase().indexOf(lowFind)) !== -1) {
str += remainder.substr(0, idx) + replace;
remainder = remainder.substr(idx + find.length);
}
return str + remainder;
}
// example call:
insensitiveReplaceAll("Find aBcc&def stuff ABCabc", "abc", "ab");
function insensitiveReplaceAll(original, find, replace) {
var str = "",
remainder = original,
lowFind = find.toLowerCase(),
idx;
while ((idx = remainder.toLowerCase().indexOf(lowFind)) !== -1) {
str += remainder.substr(0, idx) + replace;
remainder = remainder.substr(idx + find.length);
}
return str + remainder;
}
function escapeRegex(value) {
return value.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&");
}
function updateResult() {
var original = document.getElementById("original").value || "",
find = document.getElementById("find").value || "",
replace = document.getElementById("replace").value || "",
resultEl = document.getElementById("result"),
regexEl = document.getElementById("regex");
if (original && find && replace) {
regexEl.value = original.replace(new RegExp(escapeRegex(find), "gi"), replace);
resultEl.value = insensitiveReplaceAll(original, find, replace);
} else {
regexEl.value = "";
resultEl.value = "";
}
}
document.addEventListener("input", updateResult);
window.addEventListener("load", updateResult);

<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" rel="stylesheet" />
<div class="input-group input-group-sm">
<span class="input-group-addon">Original</span>
<input class="form-control" id="original" value="Find aBcc&def stuff ABCabc" />
</div>
<div class="input-group input-group-sm">
<span class="input-group-addon">Find</span>
<input class="form-control" id="find" value="abc" />
</div>
<div class="input-group input-group-sm">
<span class="input-group-addon">Replace</span>
<input class="form-control" id="replace" value="ab" />
</div>
<div class="input-group input-group-sm">
<span class="input-group-addon">Result w/o regex</span>
<input disabled class="form-control" id="result" />
</div>
<div class="input-group input-group-sm">
<span class="input-group-addon">Result w/ regex</span>
<input disabled class="form-control" id="regex" />
</div>
&#13;
答案 1 :(得分:1)
var s="aBc&def stuff ABCabc"
var idx = s.toUpperCase().indexOf("ABC");
while(idx!==-1){
s = s.substr(0,idx)+"x"+s.substr(idx+2);
idx = s.toUpperCase().indexOf("ABC");
}
答案 2 :(得分:1)
function replace(s, q, r) {
var result = '';
for (var i = 0; i < s.length; i++) {
var j = 0;
for (; j < q.length; j++) {
if (s[i + j].toLowerCase() != q[j].toLowerCase()) break;
}
if (j == q.length) {
i += q.length - 1;
result += r;
} else {
result += s[i];
}
}
return result;
}
该函数接受参数:
r - 替换字符串(对于每个搜索查询实例)
通过迭代每个位置来工作。
在每个位置,它会尝试检查匹配项(通过.toLowerCase()
不区分大小写)。
找到的每个匹配项,都会将替换字符串插入到结果中。否则,它只是将不匹配复制到结果中。
答案 3 :(得分:1)
批准的解决方案在循环内调用toLowerCase,效率不高。
以下是改进版本:
Reports
&#13;
使用jsPerf进行测试 - https://jsperf.com/replace-case-insensitive-2/1 - 显示速度提高了37%。
答案 4 :(得分:0)
嗯,如果不考虑性能,你可能想要遍历字符串的字符以找到所需的字符串以进行替换。这样的事,也许......
for (var x = 0; x < inputString.length-3; x++) {
if (inputString.toLowerCase.substring(x, x+2) == 'abc') {
inputString = inputString.substring(0, x-1) + 'x' + inputString.substring(x+3);
x = x - 2 //because your replacement is shorter you need to back up where the index is
}
}