我有这个字符串:
"Test abc test test abc test test test abc test test abc"
干
str = str.replace('abc', '');
似乎只删除了第一次出现的 abc
在上面的字符串中。我怎样才能更换 所有 发生了吗?
我有这个字符串:
"Test abc test test abc test test test abc test test abc"
干
str = str.replace('abc', '');
似乎只删除了第一次出现的 abc
在上面的字符串中。我怎样才能更换 所有 发生了吗?
为了完整起见,我开始考虑使用哪种方法来完成这项工作。根据本页其他答案的建议,基本上有两种方法可以做到这一点。
注意: 通常,通常不建议在JavaScript中扩展内置原型。我提供String原型的扩展仅仅是为了说明的目的,显示了假设标准方法的不同实现 String
内置原型。
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);
};
在效率方面我不太了解正则表达式如何在幕后工作,我倾向于倾向于分裂并在过去加入实现而不考虑性能。当我确实想知道哪个更有效率,以及在什么边缘时,我用它作为借口来找出答案。
在我的Chrome Windows 8计算机上, 基于正则表达式的实现是最快的随着 拆分和连接实现速度慢了53%。这意味着正则表达式的速度是我使用的lorem ipsum输入的两倍。
看看这个 基准 相互运行这两个实现。
正如@ThomasLeduc和其他人在下面的评论中指出的那样,基于正则表达式的实现可能存在问题,如果 search
包含保留为的某些字符 正则表达式中的特殊字符。该实现假定调用者将事先转义字符串,或者只传递没有表中字符的字符串 常用表达 (MDN)。
MDN还提供了一种逃避字符串的实现。如果这也被标准化,那将是很好的 RegExp.escape(str)
,但唉,它不存在:
function escapeRegExp(str) {
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string
}
我们可以打电话 escapeRegExp
在我们的 String.prototype.replaceAll
但是,我不确定这会对性能产生多大影响(甚至可能对于不需要转义的字符串,例如所有字母数字字符串)。
str = str.replace(/abc/g, '');
回应评论:
var find = 'abc';
var re = new RegExp(find, 'g');
str = str.replace(re, '');
回应 单击“Upvote”的评论,你可以更简化它:
function replaceAll(str, find, replace) {
return str.replace(new RegExp(find, 'g'), replace);
}
注意: 正则表达式包含特殊(元)字符,因此盲目地传递参数是危险的 find
上面的函数没有预处理它来逃避这些字符。这包含在 Mozilla开发者网络的 关于正则表达式的JavaScript指南,它们提供以下实用功能:
function escapeRegExp(str) {
return str.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1");
}
所以为了做到 replaceAll()
如果您还包括,则可以将其修改为以下功能 escapeRegExp
:
function replaceAll(str, find, replace) {
return str.replace(new RegExp(escapeRegExp(find), 'g'), replace);
}
注意:不要在实际代码中使用它。
作为简单文字字符串的正则表达式的替代,您可以使用
str = "Test abc test test abc test...".split("abc").join("");
一般模式是
str.split(search).join(replacement)
在某些情况下,这比使用更快 replaceAll
和正则表达式,但在现代浏览器中似乎不再是这种情况。因此,这应该只是用作快速入侵,以避免需要转义正则表达式,而不是真正的代码。
使用正则表达式 g
标志集将替换所有:
someString = 'the cat looks like a cat';
anotherString = someString.replace(/cat/g, 'dog');
// anotherString now contains "the dog looks like a dog"
这是一个基于接受的答案的字符串原型函数:
String.prototype.replaceAll = function (find, replace) {
var str = this;
return str.replace(new RegExp(find, 'g'), replace);
};
编辑
如果你的 find
将包含特殊字符,然后您需要转义它们:
String.prototype.replaceAll = function (find, replace) {
var str = this;
return str.replace(new RegExp(find.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'), 'g'), replace);
};
更新:
这是一个更新有点迟,但因为我偶然发现了这个问题,并注意到我以前的答案不是我很满意的答案。由于问题涉及替换单个单词,所以没有人想到使用单词边界(\b
)
'a cat is not a caterpillar'.replace(/\bcat\b/gi,'dog');
//"a dog is not a caterpillar"
这是一个简单的正则表达式,可以避免在大多数情况下替换部分单词。但是,一个破折号 -
仍然被认为是一个词边界。因此在这种情况下可以使用条件来避免替换字符串 cool-cat
:
'a cat is not a cool-cat'.replace(/\bcat\b/gi,'dog');//wrong
//"a dog is not a cool-dog" -- nips
'a cat is not a cool-cat'.replace(/(?:\b([^-]))cat(?:\b([^-]))/gi,'$1dog$2');
//"a dog is not a cool-cat"
基本上,这个问题和这里的问题是一样的: Javascript将“'”替换为“''”
@Mike,检查我给出的答案... regexp不是替换多次出现的替换的唯一方法,远非它。思考灵活,思考分裂!
var newText = "the cat looks like a cat".split('cat').join('dog');
或者,为了防止替换单词部分 - 批准的答案也会这样做!你可以使用正则表达式来解决这个问题,我承认,这些正则表达式稍微复杂一些,并且作为结果,也有点慢:
var regText = "the cat looks like a cat".replace(/(?:(^|[^a-z]))(([^a-z]*)(?=cat)cat)(?![a-z])/gi,"$1dog");
输出与接受的答案相同,但是,在此字符串上使用/ cat / g表达式:
var oops = 'the cat looks like a cat, not a caterpillar or coolcat'.replace(/cat/g,'dog');
//returns "the dog looks like a dog, not a dogerpillar or cooldog" ??
哎呀,这可能不是你想要的。那是什么?恕我直言,一个只有条件地取代'猫'的正则表达式。 (即不是单词的一部分),如下:
var caterpillar = 'the cat looks like a cat, not a caterpillar or coolcat'.replace(/(?:(^|[^a-z]))(([^a-z]*)(?=cat)cat)(?![a-z])/gi,"$1dog");
//return "the dog looks like a dog, not a caterpillar or coolcat"
我的猜测是,这符合您的需求。当然,这不是全面的,但它应该足以让你开始。我建议在这些页面上阅读更多内容。这对于完善此表达式以满足您的特定需求非常有用。
http://www.javascriptkit.com/jsref/regexp.shtml
http://www.regular-expressions.info
最后补充:
鉴于这个问题仍然有很多观点,我想我可能会添加一个例子 .replace
与回调函数一起使用。在这种情况下,它大大简化了表达式 和 提供更大的灵活性,例如替换正确的大写或替换两者 cat
和 cats
一气呵成:
'Two cats are not 1 Cat! They\'re just cool-cats, you caterpillar'
.replace(/(^|.\b)(cat)(s?\b.|$)/gi,function(all,char1,cat,char2)
{
//check 1st, capitalize if required
var replacement = (cat.charAt(0) === 'C' ? 'D' : 'd') + 'og';
if (char1 === ' ' && char2 === 's')
{//replace plurals, too
cat = replacement + 's';
}
else
{//do not replace if dashes are matched
cat = char1 === '-' || char2 === '-' ? cat : replacement;
}
return char1 + cat + char2;//return replacement string
});
//returns:
//Two dogs are not 1 Dog! They're just cool-cats, you caterpillar
匹配全局正则表达式:
anotherString = someString.replace(/cat/g, 'dog');