在特定索引位置插入一个字符串。

459

我该如何在另一个字符串的特定索引处插入一个字符串?

 var txt1 = "foo baz"

假设我想在“foo”后面插入“bar”,我该如何实现?

我考虑使用substring(),但肯定有更简单、更直接的方法。


3
如何在JavaScript中替换特定索引处的字符? - Mr_Green
20个回答

586

在特定位置插入(而不是在第一个空格字符处插入)必须使用字符串切片/子字符串:

var txt2 = txt1.slice(0, 3) + "bar" + txt1.slice(3);

5
"substring"在这里也可以,但我一般更喜欢使用"slice",因为它更加灵活(支持负索引,例如:"foo baz".slice(1, -2))。而且相比之下稍微更短一些。 - Tim Down
19
ES6提供了更好的选择吗?至少可以使用字符串插值,例如\${txt1.slice(0,3)}bar${txt1.slice(3)}``。 - Jay
3
这不使用包含在上面的顶级答案中的“删除”功能... - Mr. Polywhirl
19
@Mr.Polywhirl: 不需要这样做,问题中没有提到这一点。 - Tim Down

298

你可以将自己的splice()原型化为字符串。

填充

if (!String.prototype.splice) {
    /**
     * {JSDoc}
     *
     * The splice() method changes the content of a string by removing a range of
     * characters and/or adding new characters.
     *
     * @this {String}
     * @param {number} start Index at which to start changing the string.
     * @param {number} delCount An integer indicating the number of old chars to remove.
     * @param {string} newSubStr The String that is spliced in.
     * @return {string} A new string with the spliced substring.
     */
    String.prototype.splice = function(start, delCount, newSubStr) {
        return this.slice(0, start) + newSubStr + this.slice(start + Math.abs(delCount));
    };
}

例子

String.prototype.splice = function(idx, rem, str) {
    return this.slice(0, idx) + str + this.slice(idx + Math.abs(rem));
};

var result = "foo baz".splice(4, 0, "bar ");

document.body.innerHTML = result; // "foo bar baz"


编辑:修改以确保rem是绝对值。


11
我知道这是2010年的内容,但以下的“切片(slice)”解决方案更好且更简单。(splice是具有破坏性的,而slice则不是,最好避免修改“你不了解的对象”)。即使在当时它可能很有意义,但这个解决方案绝对不应该成为首选答案。 - Eirik Birkeland
7
字符串是不可变的。上面的代码不会修改任何对象。无论如何,你对不修改“你不知道的对象”的概念将排除数组突变方法。你是说你宁愿使用my_array[my_array.length] = item而不是my_array.push(item)吗? - user1106925
5
抱歉,我想表达的是“你不拥有的对象”。在这种情况下,你关于splice的说法是正确的;事实上,字符串是不可变的。因此,我认为splice是一个不恰当的关键词选择。我的主要反对意见是非标准填充(standard polyfills)的原型扩展应该被避免。 - Eirik Birkeland
5
修改内置对象是一种非常糟糕的做法。正如我们在SmooshGate中看到的那样,这可能会破坏您的代码,因为语言添加了新功能。如果您的不负责任的修改某种方式进入了一个库,并在Web上得到广泛使用,它可能会阻止新功能使用一个简单、清晰的方法名称。 - Sean
你也可以实际上使用splice来插入一个字符串,但它会返回被移除的元素,因此需要多行代码。它可能性能不佳(虽然没有正则表达式逐个字符遍历那么糟糕):const characters = [...originalString]; characters.splice(index, replaceCharCount, stringToInsert); const newString = characters.join("") - undefined

160

我写了一个与其他编程语言行为相同的方法:

String.prototype.insert = function(index, string) {
  if (index > 0)
  {
    return this.substring(0, index) + string + this.substring(index, this.length);
  }

  return string + this;
};

//Example of use:
var something = "How you?";
something = something.insert(3, " are");
console.log(something)

Reference:


1
你可能需要在if-else块中添加花括号{} - Mr-IDE
3
不需要,但是 else 是多余的。 - Bitterblue

91

请编写以下函数:

function insert(str, index, value) {
    return str.substr(0, index) + value + str.substr(index);
}

然后像这样使用:

alert(insert("foo baz", 4, "bar "));

输出结果:foo bar baz

它的行为与C#(Sharp)中的String.Insert(int startIndex, string value)几乎完全相同。

注意:此插入函数会在字符串str(第一个参数)中指定的整数index(第二个参数)之前插入字符串value(第三个参数),然后返回新字符串而不更改str


19
  1. 从字符串实例化一个数组
  2. 使用 Array#splice
  3. 再次使用 Array#join 进行字符串化

这种方法的好处有两个:

  1. 简单易懂
  2. 符合 Unicode 编码标准

const pair = Array.from('USDGBP')
pair.splice(3, 0, '/')
console.log(pair.join(''))


1
这实际上是一个非常简单的解决方案,我会说这是最好的选择,你也可以内联它,但现在这样也不错。 - Brooks DuBois

19

2016年更新: 这里有另一个基于一行代码的RegExp方法的只是为了好玩(但更加严谨!),支持在undefined或负index下插入的前置功能:

/**
 * Insert `what` to string at position `index`.
 */
String.prototype.insert = function(what, index) {
    return index > 0
        ? this.replace(new RegExp('.{' + index + '}'), '$&' + what)
        : what + this;
};

console.log( 'foo baz'.insert('bar ', 4) );  // "foo bar baz"
console.log( 'foo baz'.insert('bar ')    );  // "bar foo baz"

之前(回到2012年)的“只是为了好玩”的解决方案:

var index = 4,
    what  = 'bar ';

'foo baz'.replace(/./g, function(v, i) {
    return i === index - 1 ? v + what : v;
});  // "foo bar baz"

1
如果您需要在字符串中的多个索引处插入文本,这也非常好。如果是这种情况,请参见我的下面的答案。 - Jake Stoeffler
不需要像这样修改内置对象的原型。这是不好的形式。 - Heretic Monkey
2023年的更新,我建议使用正向后行断言:originalString.replace( new RegExp( (?<=.{${ index }}), "su" ), stringToInsert )它会自动匹配字符串的开头,无需使用开头锚点。为什么这样一个非常标准的操作在原生JS中仍然不可用呢? - undefined

19

我基本上正在做@Base33所做的事情,只是我还提供了使用负索引从末尾计数的选项。有点像substr方法允许的那样。

// use a negative index to insert relative to the end of the string.

String.prototype.insert = function (index, string) {
  var ind = index < 0 ? this.length + index  :  index;
  return  this.substring(0, ind) + string + this.substr(ind);
};

例如:假设您有按照命名约定的全尺寸图像,但无法更新数据以提供缩略图URL。

var url = '/images/myimage.jpg';
var thumb = url.insert(-4, '_thm');

//    result:  '/images/myimage_thm.jpg'

2
不需要像这样修改内置对象的原型。这是不好的形式。 - Heretic Monkey

18

如果有人正在寻找一种在字符串中插入文本的多个索引的方法,请尝试以下方法:

String.prototype.insertTextAtIndices = function(text) {
    return this.replace(/./g, function(character, index) {
        return text[index] ? text[index] + character : character;
    });
};

例如,您可以使用此功能在字符串中的特定偏移处插入<span>标签:

var text = {
    6: "<span>",
    11: "</span>"
};

"Hello world!".insertTextAtIndices(text); // returns "Hello <span>world</span>!"

1
我尝试了这种方法,但是用变量替换了'6'和'11'后它不起作用 - 我做错了什么 - 请帮忙。提前感谢 :) - Dex Dave
1
6和11是字符串插入的索引。6: "<span>"表示在索引6处插入文本"<span>"。您是说要使用整数变量的值作为插入索引吗?如果是这样,请尝试类似于var a=6, text = {}; text[a] = "<span>";的方法。 - Jake Stoeffler
1
是的,我想使用整数变量作为插入,你的方法很有效 - 谢谢你 - 这是我使用的代码:var a=6; var b=11; text = {}; text[a] = "xx";text[b] = "yy"; - 不过有更好的写法吗? - Dex Dave
不需要像这样修改内置对象的原型。这是不好的形式。 - Heretic Monkey

10

考虑到您当前的示例,您可以通过以下方式实现结果:

var txt2 = txt1.split(' ').join(' bar ')
或者
var txt2 = txt1.replace(' ', ' bar ');

但是,如果您能够做出这样的假设,那么最好直接跳到Gullen的示例。

在您确实无法做出任何假设而只能依赖于字符索引时,我会选择使用子字符串解决方案。


8
my_string          = "hello world";
my_insert          = " dear";
my_insert_location = 5;

my_string = my_string.split('');  
my_string.splice( my_insert_location , 0, my_insert );
my_string = my_string.join('');

https://jsfiddle.net/gaby_de_wilde/wz69nw9k/


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接