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

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

var str = "hello world";

我需要像

str.replaceAt(0,"h");
833147 次浏览

您不能。获取位置前后的字符并合并为一个新字符串:

var s = "Hello world";
var index = 3;
s = s.substring(0, index) + 'x' + s.substring(index + 1);

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

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>

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

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

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

并像这样使用它:

var hello = "Hello World";
alert(hello.replaceAt(2, "!!")); // He!!o World

在JavaScript中,字符串是不可变的,因此您必须执行以下操作

var x = "Hello world"
x = x.substring(0, i) + 'h' + x.substring(i+1);

将x中的字符i替换为'h'

这里的方法很复杂。 我会这样做:

var myString = "this is my string";
myString = myString.replace(myString.charAt(number goes here), "insert replacement here");

这是最简单的。

使用向量通常对联系String最有效。

我建议使用以下功能:

String.prototype.replaceAt=function(index, char) {
var a = this.split("");
a[index] = char;
return a.join("");
}

运行此代码段:

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);

@CemKalyoncu:谢谢你的精彩回答!

我还稍微修改了它,使其更像Array.splice方法(并考虑了@Ates的笔记):

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!"

这类似于Array.splice

String.prototype.splice = function (i, j, str) {
return this.substr(0, i) + str + this.substr(j, this.length);
};

这里有很多答案,所有这些答案都基于两种方法:

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

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

@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(数组转换)。

结果:

  • 测试1:195ms
  • 测试2:6ms

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

实际发生的是TEST2中的所有操作都是在数组本身上完成的,使用像strarr2[p] = n这样的赋值表达式。与大字符串上的子字符串相比,赋值真的很快,很明显它会赢。

所以,这都是关于为工作选择合适的工具。再一次。

str = str.split('');
str[3] = 'h';
str = str.join('');

我做了一个类似于你问的函数,它检查字符串中的字符是否在不允许字符的数组中,如果是,它将其替换为“

    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;
}

该解决方案不适用于负索引,因此我为其添加了一个补丁。

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方法:

String.prototype.append = function (index,value) {
return this.slice(0,index) + value + this.slice(index);
};


var s = "New string";
alert(s.append(4,"complete "));

然后您可以调用该函数:

如果您想替换字符串中的字符,您应该创建可变字符串。这些本质上是字符数组。您可以创建一个工厂:

  function MutableString(str) {
var result = str.split("");
result.toString = function() {
return this.join("");
}
return result;
}

然后您可以访问字符,当用作字符串时,整个数组将转换为字符串:

  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!"

假设您想将Kth索引(基于0的索引)替换为'Z'。 您可以使用Regex来执行此操作。

var re = var re = new RegExp("((.){" + K + "})((.){1})")
str.replace(re, "$1A$`");

function dothis() {
var x = document.getElementById("x").value;
var index = document.getElementById("index").value;
var text = document.getElementById("text").value;
var length = document.getElementById("length").value;
var arr = x.split("");
arr.splice(index, length, text);
var result = arr.join("");
document.getElementById('output').innerHTML = result;
console.log(result);
}
dothis();
<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="length" type="number" min="0"value="1" style="width:50px" placeholder="length" />
<input id="text" type="text" value="F" placeholder="New character" />
<br>
<button id="submit" onclick="dothis()">Run</button>
<p id="output"></p>

此方法适用于较小长度的字符串,但对于较大的文本可能会很慢。

var x = "White Dog";
var arr = x.split(""); // ["W", "h", "i", "t", "e", " ", "D", "o", "g"]
arr.splice(6, 1, 'F');


/*
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.
*/
var result = arr.join(""); // "White Fog"

使用带有回调的String.replace的单行代码(不支持表情符号):

// 0 - index to replace, 'f' - replacement string
'dog'.replace(/./g, (c, i) => i == 0? 'f': c)
// "fog"

解释:

//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
})

你可以试试

var strArr = str.split("");


strArr[0] = 'h';


str = strArr.join("");

这是我想出的一个版本,如果你想在react/javascript的索引中设置单词或单个字符的样式。

replaceAt( yourArrayOfIndexes, yourString/orArrayOfStrings )

工作示例:https://codesandbox.io/s/ov7zxp9mjq

function replaceAt(indexArray, [...string]) {
const replaceValue = i => string[i] = <b>{string[i]}</b>;
indexArray.forEach(replaceValue);
return string;
}

这是另一种替代方法

function replaceAt(indexArray, [...string]) {
const startTag = '<b>';
const endTag = '</b>';
const tagLetter = i => string.splice(i, 1, startTag + string[i] + endTag);
indexArray.forEach(tagLetter);
return string.join('');
}

还有一个…

function replaceAt(indexArray, [...string]) {
for (let i = 0; i < indexArray.length; i++) {
string = Object.assign(string, {
[indexArray[i]]: <b>{string[indexArray[i]]}</b>
});
}
return string;
}

您可以使用以下函数在String的特定位置替换CharacterString。要替换所有以下匹配用例,请使用String.prototype.replaceAllMatches()函数。

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;
};

测试:

var str = "yash yas $dfdas.**";


console.log('Index Matched replace : ', str.replaceMatch('as', '*', 2) );
console.log('Index Matched replace : ', str.replaceMatch('y', '~', 1) );

输出:

Index Matched replace :  yash yas $dfd*.**
Index Matched replace :  yash ~as $dfdas.**

这很容易与RegExp实现!

const str = 'Hello RegEx!';
const index = 11;
const replaceWith = 'p';


//'Hello RegEx!'.replace(/^(.{11})(.)/, `$1p`);
str.replace(new RegExp(`^(.{${ index }})(.)`), `$1${ replaceWith }`);


//< "Hello RegExp"

概括Afanasii Kurakin的回答,我们有:

function replaceAt(str, index, ch) {
return str.replace(/./g, (c, i) => i == index ? ch : c);
}


let str = 'Hello World';
str = replaceAt(str, 1, 'u');
console.log(str); // Hullo World

让我们扩展和解释正则表达式和替换函数:

function replaceAt(str, index, newChar) {
function replacer(origChar, strIndex) {
if (strIndex === index)
return newChar;
else
return origChar;
}
return str.replace(/./g, replacer);
}


let str = 'Hello World';
str = replaceAt(str, 1, 'u');
console.log(str); // Hullo World

正则表达式.正好匹配一个字符。g使其匹配for循环中的每个字符。给定原始字符和该字符在字符串中的位置的索引,调用replacer函数。我们做了一个简单的if语句来确定我们是要返回origChar还是newChar

这是我使用三元和map运算符的解决方案。如果你问我,更具可读性,可维护性,更容易理解。

它更多的是es6和最佳实践。

function replaceAt() {
const replaceAt = document.getElementById('replaceAt').value;


const str = 'ThisIsATestStringToReplaceCharAtSomePosition';
const newStr = Array.from(str).map((character, charIndex) => charIndex === (replaceAt - 1) ? '' : character).join('');


console.log(`New string: ${newStr}`);
}
<input type="number" id="replaceAt" min="1" max="44" oninput="replaceAt()"/>

var str = "hello world";
console.log(str);
var arr = [...str];
arr[0] = "H";
str = arr.join("");
console.log(str);

您可以使用子字符串函数连接,首先在目标索引之前选择文本,然后在目标索引之后连接您的潜在字符或字符串。这个更好

const myString = "Hello world";
const index = 3;
const stringBeforeIndex = myString.substring(0, index);
const stringAfterIndex = myString.substring(index + 1);
const replaceChar = "X";
myString = stringBeforeIndex + replaceChar + stringAfterIndex;
console.log("New string - ", myString)

const myString = "Hello world";
let index = 3;
myString =  myString.substring(0, index) + "X" + myString.substring(index + 1);

你可以试试

var strArr = str.split("");


strArr[0] = 'h';


str = strArr.join("");

打印步骤查看此功能

steps(3)
//       '#  '
//       '## '
//       '###'


function steps(n, i = 0, arr = Array(n).fill(' ').join('')) {
if (i === n) {
return;
}


str = arr.split('');
str[i] = '#';
str = str.join('');
console.log(str);


steps(n, (i = i + 1), str);
}


使用扩展语法,您可以将字符串转换为数组,在给定位置分配字符,然后将其转换回字符串:

const str = "hello world";


function replaceAt(s, i, c) {
const arr = [...s];  // Convert string to array
arr[i] = c;          // Set char c at pos i
return arr.join(''); // Back to string
}


// prints "hallo world"
console.log(replaceAt(str, 1, 'a'));

我用负指数的安全方法

/**
* @param {string} str
* @param {number} index
* @param {string} replacement
* @returns {string}
*/
static replaceAt (str, index, replacement)
{
if (index < 0) index = str.length + index
if (index < 0 || index >= str.length) throw new Error(`Index (${index}) out of bounds "${str}"`)
return str.substring(0, index) + replacement + str.substring(index + 1)
}

像这样使用它:

replaceAt('my string', -1, 'G') // 'my strinG'
replaceAt('my string', 2, 'yy') // 'myyystring'
replaceAt('my string', 22, 'yy') // Uncaught Error: Index (22) out of bounds "my string"

我这样做是为了使字符串正确的大小写,即第一个字母是大写,其余的都是小写:

function toProperCase(someString){
    

return someString.charAt(0).toUpperCase().concat(someString.toLowerCase().substring(1,someString.length));
    

};

首先要做的是确保所有字符串都是小写-someString.toLowerCase()

然后它将第一个字符转换为大写-someString.charAt(0).toUpperCase()

然后它接受剩余字符串的子字符串减去第一个字符-someString.toLowerCase().substring(1,someString.length))

然后它将两者连接并返回新字符串-someString.charAt(0).toUpperCase().concat(someString.toLowerCase().substring(1,someString.length))

可以为替换字符索引和替换字符添加新参数,然后形成两个子字符串,替换索引字符,然后以几乎相同的方式连接。

"hello world".replace(/(.{3})./, "$1h")
// 'helho world'