如何替换 JavaScript 中特定索引处的字符?

IT技术 javascript string replace character-replacement
2021-01-11 00:33:39

我有一个字符串,假设Hello world我需要替换索引 3 处的字符。如何通过指定索引来替换字符?

var str = "hello world";

我需要类似的东西

str.replaceAt(0,"h");
6个回答

在 JavaScript 中,字符串是不可变的,这意味着你能做的最好的事情就是用改变的内容创建一个新的字符串并分配变量来指向它。

您需要自己定义replaceAt()函数:

String.prototype.replaceAt = function(index, replacement) {
    return this.substr(0, index) + replacement + this.substr(index + replacement.length);
}

并像这样使用它:

var hello = "Hello World";
alert(hello.replaceAt(2, "!!")); // He!!o World
我不同意,即使您检测到该函数是否存在,后来的库仍可能使用/创建类似的函数——2 个坏主意使一个更糟。一般来说,永远不要玩弄别人的代码(包括核心系统)。创建一个新函数。
2021-03-15 00:33:39
请注意,扩展基本 JavaScript 类通常不是一个好主意。改用普通的实用程序函数。
2021-03-22 00:33:39
@alex:您是对的,您确实需要在执行该函数之前检查该函数是否存在。但即使这样做,它也应该执行完全相同的操作。
2021-03-23 00:33:39
我必须问为什么?为此目的提供原型支持。
2021-03-28 00:33:39
@CemKalyoncu:它可以使代码与其他库一起玩不好。但我自己从来没有被它咬过。
2021-04-03 00:33:39

replaceAtJavaScript 中没有函数。您可以使用以下代码替换任何字符串中指定位置的任何字符:

function rep() {
    var str = 'Hello World';
    str = setCharAt(str,4,'a');
    alert(str);
}

function setCharAt(str,index,chr) {
    if(index > str.length-1) return str;
    return str.substring(0,index) + chr + str.substring(index+1);
}
<button onclick="rep();">click</button>

@ScottTesler - 这个答案使用substring, not substr... 并且在您的链接中它说这两个函数是“遗留”还是应该避免?...substringsubstr用于不同的目的
2021-03-19 00:33:39
我更喜欢这个解决方案,因为您可以用它替换单个字符。如果您只想替换一个字符,则拥有最多投票的解决方案将不起作用。它仅在替换两个字符时有效!此外, substr 应该替换为 substring ,如许多​​其他评论中所述。
2021-03-31 00:33:39
在我的测试中,这种方法是迄今为止最快的……如果您不需要验证 [index] 不大于字符串长度,则速度甚至更快。修改的:function setCharAt(str,idx,newChr){ return str.substring(0,idx)+newChr+str.substring(idx+1);}
2021-04-01 00:33:39
@ashleedawg 看起来它不再被弃用。
2021-04-03 00:33:39

你不能。取位置前后的字符并连接成一个新的字符串:

var s = "Hello world";
var index = 3;
s = s.substring(0, index) + 'x' + s.substring(index + 1);
@Ates:replace 函数不会进行就地替换,它会创建一个新字符串并返回它。
2021-03-22 00:33:39
MDN建议使用String.prototype.substringover String.prototype.substr
2021-03-29 00:33:39
实际上,是的,您可以,但这将是一种矫枉过正。您可以设置一个正则表达式来跳过第一个索引 - 1 个字符并匹配索引处的字符。您可以使用带有该正则表达式的 String.replace 来进行直接的就地替换。但这是一种矫枉过正。所以,在实践中你不能。但理论上,你可以。
2021-03-31 00:33:39
str = str.split('');
str[3] = 'h';
str = str.join('');
对于 es6,我认为 Array.from(str) 现在可能是更好的选择,但我带着这些知识来到这里并从你那里学到了一些同样简洁的东西,所以谢谢你!
2021-03-29 00:33:39
清晰简单,但目前在使用split时无法与表情符号(例如😀)一起使用join
2021-04-02 00:33:39
@DavidKamer 我迟到了,但似乎Array.fromstr.split. blog.shovonhasan.com/…
2021-04-08 00:33:39

这里有很多答案,它们都是基于两种方法:

  • 方法 1:使用两个子字符串拆分字符串并在它们之间填充字符
  • 方法二:将字符串转成字符数组,替换一个数组成员并加入

就个人而言,我会在不同的情况下使用这两种方法。让我解释。

@FabioPhms:你的方法是我最初使用的方法,我担心它在包含大量字符的字符串上不好。然而,问题是什么是很多字符?我在 10 个“lorem ipsum”段落上测试了它,花了几毫秒。然后我在 10 倍大的字符串上对其进行了测试 - 确实没有太大区别。嗯。

@vsync、@Cory Mawhorter:你的评论是明确的;然而,再次,什么是大字符串?我同意 32...100kb 的性能应该更好,并且应该使用 substring-variant 来进行字符替换的这一操作。

但是如果我必须进行相当多的替换会发生什么?

我需要执行我自己的测试来证明在这种情况下什么更快。假设我们有一个算法来处理一个由 1000 个字符组成的相对较短的字符串。我们预计该字符串中的每个字符平均将被替换约 100 次。所以,测试这样的代码是:

var str = "... {A LARGE STRING HERE} ...";

for(var i=0; i<100000; i++)
{
  var n = '' + Math.floor(Math.random() * 10);
  var p = Math.floor(Math.random() * 1000);
  // replace character *n* on position *p*
}

我为此创建了一个小提琴,它在这里有两个测试,TEST1(子串)和TEST2(数组转换)。

结果:

  • TEST1:195ms
  • TEST2:6ms

似乎数组转换比子字符串高 2 个数量级!所以 - 这里到底发生了什么???

实际发生的情况是 TEST2 中的所有操作都是在数组本身上完成的,使用像strarr2[p] = n. 与大字符串上的子字符串相比,赋值真的很快,而且很明显它会获胜。

因此,最重要的是为工作选择合适的工具。再次。

@colllin 对 OzrenTkalcecKrznaric 做了一些不同的事情。OzrenTkalcecKrznaric 假设字符串是静态的,并且可以在运行之前优化拆分。这不一定是真的。如果您必须在每次运行时拆分,那么子字符串方法在小字符串上的速度大约是两倍 4 倍,并且字符串越大速度越快。在我看来,这使得子字符串成为大多数用例的更好实现,除非对大型静态字符串进行大量更改。
2021-03-11 00:33:39
这就是为什么我不喜欢 javascript。没有提供如此频繁、直观、明显的用例。您可能认为 javascript 的作者会想到人们可能想要替换字符串中的字符,并且他们决定将方便的方法放入语言中。
2021-03-16 00:33:39
将您的测试移至 jsperf,结果大不相同jsperf.com/string-replace-character这一切都是为了为工作选择合适的工具;)
2021-03-19 00:33:39
问题是在 test2 上,拆分和连接在 for 循环之外,您可以将单个字符替换与多个字符替换(不公平)进行比较,第一种方法对于单个替换更快,而第二种方法对于一个接一个的链式替换更好
2021-03-19 00:33:39
@colllin:我完全同意。所以我几乎从字面上将测试从 jsfiddle 克隆到 jsperf。但是,除了使用正确的工具之外,您还必须以正确的方式进行操作。注意这个问题,我们说的是如果我们必须在一个算法中进行相当多的替换会发生什么。具体示例包括 10000 次替换。这意味着一项测试应包括 10000 次替换。因此,使用jsperf,我得到了相当一致的结果,请参见:jsperf.com/...
2021-04-07 00:33:39