根據一條線:
s = "Test abc test test abc test test test abc test test abc";
这似乎只是在上面的行中删除ABC的第一次出现:
s = s.replace('abc', '');
如何替代所有事件?
根據一條線:
s = "Test abc test test abc test test test abc test test abc";
这似乎只是在上面的行中删除ABC的第一次出现:
s = s.replace('abc', '');
如何替代所有事件?
当前回答
如果使用图书馆是您的选择,那么您将获得与图书馆功能一起进行的测试和社区支持的好处。
// Include a reference to the string.js library and call it (for example) S.
str = S(str).replaceAll('abc', '').s;
其他回答
基于定期表达的实施
String.prototype.replaceAll = function(search, replacement) {
var target = this;
return target.replace(new RegExp(search, 'g'), replacement);
};
String.prototype.replaceAll = function(search, replacement) {
var target = this;
return target.split(search).join(replacement);
};
看看这个参数运行这两个实施对彼此。
正如 @ThomasLeduc 和其他人在下面的评论中所指出的那样,如果搜索包含某些字符,这些字符在常规表达式中被保留为特殊字符,则可能会出现常规表达式的实施问题。
MDN 还提供了一个实施,以逃避我们的线条. 如果它也被标准化为 RegExp.escape(str),但不幸的是,它不存在:
function escapeRegExp(str) {
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string
}
这是最快的版本,不使用常规表达式。
修订 JSperf
replaceAll = function(string, omit, place, prevstring) {
if (prevstring && string === prevstring)
return string;
prevstring = string.replace(omit, place);
return replaceAll(prevstring, omit, place, string)
}
它几乎比分裂和合并方法快两倍。
正如在评论中所指出的那样,如果你的错误变量包含位置,就不会工作,因为它总是能够取代另一个出现的词。
有另一个JSperf与我的回归替换的变量,它走得更快(http://jsperf.com/replace-all-vs-split-join/12)!
2017 年 7 月 27 日更新: 看起来 RegExp 现在在最近发布的 Chrome 59 中具有最快的性能。
我已经阅读了这个问题和答案,但我找不到一个合适的解决方案,虽然答案是相当有用的,我决定创建自己的解决方案从切割。
例如,对于搜索结果,我需要用相同的案例取代它,如果我处理内部HTML,我可以轻松地损害HTML标签(例如,在href属性中出现 hr)。
因此,我写的功能,以突出搜索结果在一个表,在那里表数据细胞可能有链接在内部,以及其他HTML标签。
我決定為所有人提供相同的問題的解決方案. 當然,你可以用它不僅為表,但為任何元素。
/* Iterate over table data cells to insert a highlight tag */
function highlightSearchResults(textFilter) {
textFilter = textFilter.toLowerCase().replace('<', '<').replace('>', '>');
let tds;
tb = document.getElementById('sometable'); //root element where to search
if (tb) {
tds = tb.getElementsByTagName("td"); //sub-elements where to make replacements
}
if (textFilter && tds) {
for (td of tds) {
//specify your span class or whatever you need before and after
td.innerHTML = insertCaseInsensitive(td.innerHTML, textFilter, '<span class="highlight">', '</span>');
}
}
}
/* Insert a highlight tag */
function insertCaseInsensitive(srcStr, lowerCaseFilter, before, after) {
let lowStr = srcStr.toLowerCase();
let flen = lowerCaseFilter.length;
let i = -1;
while ((i = lowStr.indexOf(lowerCaseFilter, i + 1)) != -1) {
if (insideTag(i, srcStr)) continue;
srcStr = srcStr.slice(0, i) + before + srcStr.slice(i, i+flen) + after + srcStr.slice(i+flen);
lowStr = srcStr.toLowerCase();
i += before.length + after.length;
}
return srcStr;
}
/* Check if an ocurrence is inside any tag by index */
function insideTag(si, s) {
let ahead = false;
let back = false;
for (let i = si; i < s.length; i++) {
if (s[i] == "<") {
break;
}
if (s[i] == ">") {
ahead = true;
break;
}
}
for (let i = si; i >= 0; i--) {
if (s[i] == ">") {
break;
}
if (s[i] == "<") {
back = true;
break;
}
}
return (ahead && back);
}
我的实践,非常自我解释
function replaceAll(string, token, newtoken) {
if(token!=newtoken)
while(string.indexOf(token) > -1) {
string = string.replace(token, newtoken);
}
return string;
}
最好的解决方案,以取代我们使用的任何字符的 indexOf(),包括(),和substring()功能,以取代相匹配的行与提供的行在当前行。
String.indexOf() 函数是找到 nth 匹配指数位置. String.includes() 方法确定一个行是否可以在另一个行中找到,随时返回真实或虚假。
下面的功能允许使用任何字符. 如 RegExp 不允许某些特殊字符如 ** 和某些字符需要逃避,如 $。
String.prototype.replaceAllMatches = function(obj) { // Obj format: { 'matchkey' : 'replaceStr' }
var retStr = this;
for (var x in obj) {
//var matchArray = retStr.match(new RegExp(x, 'ig'));
//for (var i = 0; i < matchArray.length; i++) {
var prevIndex = retStr.indexOf(x); // matchkey = '*', replaceStr = '$*' While loop never ends.
while (retStr.includes(x)) {
retStr = retStr.replaceMatch(x, obj[x], 0);
var replaceIndex = retStr.indexOf(x);
if( replaceIndex < prevIndex + (obj[x]).length) {
break;
} else {
prevIndex = replaceIndex;
}
}
}
return retStr;
};
String.prototype.replaceMatch = function(matchkey, replaceStr, matchIndex) {
var retStr = this, repeatedIndex = 0;
//var matchArray = retStr.match(new RegExp(matchkey, 'ig'));
//for (var x = 0; x < matchArray.length; x++) {
for (var x = 0; (matchkey != null) && (retStr.indexOf(matchkey) > -1); x++) {
if (repeatedIndex == 0 && x == 0) {
repeatedIndex = retStr.indexOf(matchkey);
} else { // matchIndex > 0
repeatedIndex = retStr.indexOf(matchkey, repeatedIndex + 1);
}
if (x == matchIndex) {
retStr = retStr.substring(0, repeatedIndex) + replaceStr + retStr.substring(repeatedIndex + (matchkey.length));
matchkey = null; // To break the loop.
}
}
return retStr;
};
我们还可以使用常规表达式对象,以匹配文本与模式,以下是将常规表达式对象使用的功能。
String.prototype.replaceAllRegexMatches = function(obj) { // Obj format: { 'matchkey' : 'replaceStr' }
var retStr = this;
for (var x in obj) {
retStr = retStr.replace(new RegExp(x, 'ig'), obj[x]);
}
return retStr;
};
请注意,常规表达式是没有引用的。
var str = "yash yas $dfdas.**";
console.log('String: ', str);
// No need to escape any special character
console.log('Index matched replace: ', str.replaceMatch('as', '*', 2));
console.log('Index Matched replace: ', str.replaceMatch('y', '~', 1));
console.log('All Matched replace: ', str.replaceAllMatches({'as': '**', 'y':'Y', '$':'-'}));
console.log('All Matched replace : ', str.replaceAllMatches({'**': '~~', '$':'&$&', '&':'%', '~':'>'}));
// You need to escape some special Characters
console.log('REGEX all matched replace: ', str.replaceAllRegexMatches({'as' : '**', 'y':'Y', '\\$':'-'}));
结果:
String: yash yas $dfdas.**
Index Matched replace: yash yas $dfd*.**
Index Matched replace: yash ~as $dfdas.**
All Matched replace: Y**h Y** -dfd**.**
All Matched replace: yash yas %$%dfdas.>>
REGEX All Matched replace: Y**h Y** -dfd**.**