How do I replace a character at a particular index in JavaScript?
我有一个字符串,比如
1 | var str ="hello world"; |
我需要类似的东西
1 | str.replaceAt(0,"h"); |
在JavaScript中,字符串是不可变的,这意味着您可以做的最好的事情就是创建一个包含更改内容的新字符串,并分配变量指向它。
您需要自己定义
1 2 3 | String.prototype.replaceAt=function(index, replacement) { return this.substr(0, index) + replacement+ this.substr(index + replacement.length); } |
像这样使用:
1 2 | var hello="Hello World"; alert(hello.replaceAt(2,"!!")); //should display He!!o World |
javascript中没有
1 2 3 4 5 6 7 8 9 10 | 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.substr(0,index) + chr + str.substr(index+1); } |
1 | <button onclick="rep();">click</button> |
不能。将位置前后的字符和concat转换为新字符串:
1 2 3 | var s ="Hello world"; var index = 3; s = s.substr(0, index) + 'x' + s.substr(index + 1); |
这里有很多答案,它们都基于两种方法:
- 方法1:使用两个子字符串拆分字符串,并在它们之间填充字符
- 方法2:将字符串转换为字符数组,替换一个数组成员并将其联接
就个人而言,我会在不同的情况下使用这两种方法。让我解释一下。
@Fabiophms:您的方法是我最初使用的方法,我担心它在包含大量字符的字符串上是不好的。然而,问题是什么是很多字符?我在10个"lorem ipsum"段落上测试了它,花费了几毫秒。然后我在10倍大的绳子上测试了它——实际上没有什么大的区别。嗯。
@vsync,@cory mawhorter:你的评论很明确,但是,又一次,什么是大字符串?我同意对于32…100kb的性能应该更好,并且对于这个字符替换操作应该使用子字符串变量。
但是如果我必须做一些替换会发生什么呢?
我需要做我自己的测试来证明在这种情况下什么更快。假设我们有一个算法,可以处理由1000个字符组成的相对较短的字符串。我们预计该字符串中的每个字符平均将被替换约100次。所以,测试类似这样东西的代码是:
1 2 3 4 5 6 7 8 | 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(数组转换)。
结果:
- 测试1:195MS
- 测试2: 6MS
似乎数组转换比子字符串强2个数量级!那么-这里到底发生了什么????
实际发生的是,test2中的所有操作都是在数组本身上完成的,使用类似
所以,关键是为工作选择合适的工具。再一次。
使用向量通常对接触字符串最有效。
我建议以下功能:
1 2 3 4 5 | String.prototype.replaceAt=function(index, char) { var a = this.split(""); a[index] = char; return a.join(""); } |
运行此代码段:
1 2 3 4 5 6 7 8 9 10 | String.prototype.replaceAt=function(index, char) { var a = this.split(""); a[index] = char; return a.join(""); } var str ="hello world"; str = str.replaceAt(3,"#"); document.write(str); |
1 2 3 | str = str.split(''); str[3] = 'h'; str = str.join(''); |
在javascript中,字符串是不可变的,因此您必须执行如下操作
1 2 | var x ="Hello world" x = x.substring(0, i) + 'h' + x.substring(i+1); |
将i处x中的字符替换为"h"
1 2 3 4 5 6 7 8 9 10 11 | function dothis() { var x = document.getElementById("x").value; var index = document.getElementById("index").value; var text = document.getElementById("text").value; var arr = x.split(""); arr.splice(index, 1, text); var result = arr.join(""); document.getElementById('output').innerHTML = result; console.log(result); } dothis(); |
1 2 3 4 5 6 7 | <input id="x" type="text" value="White Dog" placeholder="Enter Text" /> <input id="index" type="number" min="0"value="6" style="width:50px" placeholder="index" /> <input id="text" type="text" value="F" placeholder="New character" /> <button id="submit" onclick="dothis()">Run</button> <p id="output"> </p> |
此方法适用于长度较小的字符串,但对于较大的文本可能较慢。
1 2 3 4 5 6 7 8 9 | var x ="White Dog"; var arr = x.split(""); // ["W","h","i","t","e","","D","o","g"] arr.splice(6, 1, 'F'); var result = arr.join(""); //"White Fog" /* Here 6 is starting index and 1 is no. of array elements to remove and final argument 'F' is the new character to be inserted. */ |
一个使用string.replace和callback的行程序(不支持emoji):
1 2 3 | // 0 - index to replace, 'f' - replacement string 'dog'.replace(/./g, (c, i) => i == 0? 'f': c) //"fog" |
解释:
1 2 3 4 5 6 7 | //String.replace will call the callback on each pattern match //in this case - each character 'dog'.replace(/./g, function (character, index) { if (index == 0) //we want to replace the first character return 'f' return character //leaving other characters the same }) |
这与
1 2 3 | String.prototype.splice = function (i, j, str) { return this.substr(0, i) + str + this.substr(j, this.length); }; |
@谢谢你的回答!
我还稍微调整了一下,使其更像array.splice方法(并考虑了@ates'注意事项):
1 2 3 4 5 6 | spliceString=function(string, index, numToDelete, char) { return string.substr(0, index) + char + string.substr(index+numToDelete); } var myString="hello world!"; spliceString(myString,myString.lastIndexOf('l'),2,'mhole'); //"hello wormhole!" |
我做了一个类似于你要求的函数,它检查字符串中的字符是否在一个不允许使用的字符数组中,如果是,它将用""替换它。
1 2 3 4 5 6 7 8 9 10 | var validate = function(value){ var notAllowed = [";","_",">","<","'","%","$","&","/","|",":","=","*"]; for(var i=0; i<value.length; i++){ if(notAllowed.indexOf(value.charAt(i)) > -1){ value = value.replace(value.charAt(i),""); value = validate(value); } } return value; } |
如果要替换字符串中的字符,则应创建可变字符串。这些基本上是字符数组。您可以创建一个工厂:
1 2 3 4 5 6 7 | function MutableString(str) { var result = str.split(""); result.toString = function() { return this.join(""); } return result; } |
然后,您可以访问字符,整个数组在用作字符串时转换为字符串:
1 2 3 4 | var x = MutableString("Hello"); x[0] ="B"; // yes, we can alter the character x.push("!"); // good performance: no new string is created var y ="Hi,"+x; // converted to string:"Hi, Bello!" |
你可以试试
1 2 3 4 5 | var strArr = str.split(""); strArr[0] = 'h'; str = strArr.join(""); |
这是很容易实现与regexp!
1 2 3 4 5 6 7 8 | const str = 'Hello RegEx!'; const index = 11; const replaceWith = 'p'; //'Hello RegEx!'.replace(/^(.{11})(.)/, `$1p`); str.replace(new RegExp(`^(.{${ index }})(.)`), `$1${ replaceWith }`); //<"Hello RegExp" |
假设您想用
1 2 | var re = var re = new RegExp("((.){" + K +"})((.){1})") str.replace(re,"$1A$`"); |
这是一个版本,如果你想在索引处设计单词或单个字符的样式,我会想到这个版本。
1 | replaceAt( yourArrayOfIndexes, yourString/orArrayOfStrings ) |
工作示例:https://codesandbox.io/s/pjp6jk48jj
1 2 3 4 5 6 | function replaceAt(indexArray, string) { const newString = [...string]; const replaceValue = i => (newString[i] = {newString[i]}); indexArray.map(replaceValue); return newString; } |
还有另一种方法
1 2 3 4 5 6 7 8 | function replaceAt(indexArray, inputString) { const string = [...inputString]; const startTag = ''; const endTag = ''; const tagLetter = i => string.splice(i, 1, startTag + string[i] + endTag); indexArray.forEach(tagLetter); return string.join(''); } |
而另一个…
1 2 3 4 5 6 7 8 9 10 11 | function replaceAt(indexArray, string) { let newString = [...string]; for (let i = 0; i < indexArray.length; i++) { newString = Object.assign(newString, { [indexArray[i]]: {newString[indexArray[i]]} }); } return newString; } |
我知道这是旧的,但解决方案不适用于负索引,所以我添加了一个补丁。希望它能帮助别人
1 2 3 4 5 | String.prototype.replaceAt=function(index, character) { if(index>-1) return this.substr(0, index) + character + this.substr(index+character.length); else return this.substr(0, this.length+index) + character + this.substr(index+character.length); } |
可以扩展字符串类型以包括inset方法:
1 2 3 4 5 6 | String.prototype.insert = function (index,value) { return this.substr(0, index) + value + this.substr(index,this.length); }; var s ="new function"; alert(s.insert(4,"insert string")); |
然后可以调用函数:
可以使用以下函数在字符串的特定位置替换
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | String.prototype.replaceMatch = function(matchkey, replaceStr, matchIndex) { var retStr = this, repeatedIndex = 0; 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; }; |
测试:
1 2 3 4 | var str ="yash yas $dfdas.**"; console.log('Index Matched replace : ', str.replaceMatch('as', '*', 2) ); console.log('Index Matched replace : ', str.replaceMatch('y', '~', 1) ); |
输出:
1 2 | Index Matched replace : yash yas $dfd*.** Index Matched replace : yash ~as $dfdas.** |
这里的方法很复杂。我会这样做:
1 2 | var myString ="this is my string"; myString = myString.replace(myString.charAt(number goes here),"insert replacement here"); |
这很简单。