在特定索引处插入字符串


Answers:


257

您可以将自己的原型制作splice()为String。

Polyfill

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是一个绝对值。


6
我知道这是从2010年开始的,但是下面的slice解决方案更好,更简单。(拼接是破坏性的,拼接不是破坏性的,最好避免修改“您不知道的对象”)。该解决方案绝对不应该是第一个可见的答案,即使当时可能已经有意义。
艾里克·伯克兰

6
@EirikBirkeland:字符串是不可变的。上面的代码不修改任何对象。无论哪种方式,您不修改“您不知道的对象 ”的想法都会排除Array突变方法。您说您愿意而my_array[my_array.length] = item不是my_array.push(item)

4
抱歉,我的意思是“您不拥有的对象”。splice在这种情况下,您是对的;的确字符串是不可变的。因此,我认为这splice是一个糟糕的关键词选择。我的主要反对意见是反对任意扩展原型,除非它们是标准的polyfills。
Eirik Birkeland

1
修改内置对象是非常糟糕的做法。正如我们在SmooshGate中看到的那样,这是在将新功能添加到语言中时冒着破坏代码的风险,并且,如果您不负责任的修改以某种方式进入可以在网络上广泛使用的库中,则可能会阻止使用简单明了的方法名称获得新功能。
肖恩

401

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

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

4
@AlejandroSalamancaMazuelo:substring在这里很好。slice总的来说,我更喜欢,因为它更灵活(例如,负索引"foo baz".slice(1, -2))。它也略短一些,值得一提。
蒂姆·唐

8
ES6是否提供更好的替代方案?至少可以使用字符串插值,例如`${txt1.slice(0,3)}bar${txt1.slice(3)}`
Jay

1
这没有利用上述delete功能;最佳答案 ...
Polywhirl先生,2015年

11
@ Mr.Polywhirl:不。这个问题没有提到需要这样做。
蒂姆·唐

133

这是我写的一种方法,其行为与所有其他编程语言类似:

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)

参考:


1
您可能需要{}在if-else块中添加花括号。
Mr-IDE

3
不,不需要。但是,这else是多余的。
Bitterblue

72

只需执行以下功能:

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(第一个参数)中指定的整数索引(第二个参数)之前,然后返回新字符串而不更改str


16

2016年更新:这是基于单线方法的另一个好玩的(但更严重的!)原型函数RegExp(带有prepend support undefined或negative 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
如果您需要在字符串的多个索引处插入文本,这也很棒。如果是这样,请在下面查看我的答案。
杰克·斯托弗勒

12

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

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,2015年

1
是的,我想使用整数变量作为插入,您的方法有效-谢谢-这就是我使用的var a = 6; var b = 11; 文字= {}; text [a] =“ xx”; text [b] =“ yy”; -尽管有更好的书写方式
Dex Dave 2015年

11

基本上,这是@ Bass33所做的事情,除了我还可以选择使用负索引从末尾开始计数。就像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.substring(ind, this.length);
};

用例:假设您使用命名约定拥有全尺寸图片,但无法更新数据以提供缩略图网址。

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

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

9

给定您当前的示例,您可以通过以下任一方法来获得结果

var txt2 = txt1.split(' ').join(' bar ')

要么

var txt2 = txt1.replace(' ', ' bar ');

但是鉴于您可以做出这样的假设,您不妨直接跳到Gullen的示例。

在除了基于字符索引的情况下您真的不能做任何假设的情况下,我真的会寻求子字符串解决方案。



6

我知道这是一个旧线程,但是,这是一种非常有效的方法。

var tn = document.createTextNode("I am just  to help")
t.insertData(10, "trying");

这样做的好处是可以强制节点内容。因此,如果此节点已经在DOM上,则无需使用任何查询选择器或更新innerText。更改将由于其约束而反映出来。

如果您需要一个字符串,只需访问节点的文本内容属性。

tn.textContent
#=> "I am just trying to help"

6

好吧,我们可以同时使用substring和slice方法。

String.prototype.customSplice = function (index, absIndex, string) {
    return this.slice(0, index) + string+ this.slice(index + Math.abs(absIndex));
};


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

    return string + this;
};


console.log('Hello Developers'.customSplice(6,0,'Stack ')) // Hello Stack Developers
console.log('Hello Developers'.replaceString(6,'Stack ')) //// Hello Stack Developers

子字符串方法的唯一问题是它不能与负索引一起使用。总是从第0位开始获取字符串索引。


absIndex代表什么?
EnriqueBermúdez

顺便说一句,感谢第二种方法。它就像一个魅力!
EnriqueBermúdez

5
function insertString(string, insertion, place) {
  return string.replace(string[place] + string[place + 1], string[place] + insertion + string[place + 1])
}

所以,对你来说 insertString("foo baz", "bar", 3);

显然,这将是一种绘画,因为您每次都必须向函数提供字符串,但是目前我不知道如何使它变得更容易string.replace(insertion, place)。这个想法仍然存在。


4

您可以将正则表达式与动态模式一起使用。

var text = "something";
var output = "                    ";
var pattern = new RegExp("^\\s{"+text.length+"}");
var output.replace(pattern,text);

输出:

"something      "

这将替换text.length字符串开头的空白字符output。该RegExp方法^\-开头的行的\s任何空白字符,反复{n}多次,在这种情况下text.length。使用\\\构建这种模式出来的字符串时逃跑反斜杠。


3

另一个解决方案是将字符串切成2,然后在中间插入字符串。

var str = jQuery('#selector').text();

var strlength = str.length;

strf = str.substr(0 , strlength - 5);
strb = str.substr(strlength - 5 , 5);

jQuery('#selector').html(strf + 'inserted' + strb);

3

您可以在一行代码中使用regexp轻松完成此操作

const str = 'Hello RegExp!';
const index = 6;
const insert = 'Lovely ';
    
//'Hello RegExp!'.replace(/^(.{6})(.)/, `$1Lovely $2`);
const res = str.replace(new RegExp(`^(.{${index}})(.)`), `$1${insert}$2`);
    
console.log(res);

“您好,RegExp!”


2

使用切片

您可以使用slice(0,index) + str + slice(index)。或者,您可以为其创建方法。

String.prototype.insertAt = function(index,str){
  return this.slice(0,index) + str + this.slice(index)
}
console.log("foo bar".insertAt(4,'baz ')) //foo baz bar

字符串的拼接方法

您可以split()在主字符串中添加然后使用正常splice()

String.prototype.splice = function(index,del,...newStrs){
  let str = this.split('');
  str.splice(index,del,newStrs.join('') || '');
  return str.join('');
}


 var txt1 = "foo baz"

//inserting single string.
console.log(txt1.splice(4,0,"bar ")); //foo bar baz


//inserting multiple strings
console.log(txt1.splice(4,0,"bar ","bar2 ")); //foo bar bar2 baz


//removing letters
console.log(txt1.splice(1,2)) //f baz


//remving and inseting atm
console.log(txt1.splice(1,2," bar")) //f bar baz

在多个索引上应用splice()

该方法采用一个数组数组,每个数组元素代表一个splice()

String.prototype.splice = function(index,del,...newStrs){
  let str = this.split('');
  str.splice(index,del,newStrs.join('') || '');
  return str.join('');
}


String.prototype.mulSplice = function(arr){
  str = this
  let dif = 0;
  
  arr.forEach(x => {
    x[2] === x[2] || [];
    x[1] === x[1] || 0;
    str = str.splice(x[0] + dif,x[1],...x[2]);
    dif += x[2].join('').length - x[1];
  })
  return str;
}

let txt = "foo bar baz"

//Replacing the 'foo' and 'bar' with 'something1' ,'another'
console.log(txt.splice(0,3,'something'))
console.log(txt.mulSplice(
[
[0,3,["something1"]],
[4,3,["another"]]
]

))


1

我想分别比较使用Base33和user113716的使用子字符串的方法和使用slice的方法,以此来编写一些代码

也看看这个性能比较,子串,切片

我使用的代码创建了巨大的字符串,并将字符串“ bar”多次插入了巨大的字符串

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


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

    return string + this;
};


function createString(size) {
    var s = ""
    for (var i = 0; i < size; i++) {
        s += "Some String "
    }
    return s
}


function testSubStringPerformance(str, times) {
    for (var i = 0; i < times; i++)
        str.insert(4, "bar ")
}

function testSpliceStringPerformance(str, times) {
    for (var i = 0; i < times; i++)
        str.splice(4, 0, "bar ")
}


function doTests(repeatMax, sSizeMax) {
    n = 1000
    sSize = 1000
    for (var i = 1; i <= repeatMax; i++) {
        var repeatTimes = n * (10 * i)
        for (var j = 1; j <= sSizeMax; j++) {
            var actualStringSize = sSize *  (10 * j)
            var s1 = createString(actualStringSize)
            var s2 = createString(actualStringSize)
            var start = performance.now()
            testSubStringPerformance(s1, repeatTimes)
            var end = performance.now()
            var subStrPerf = end - start

            start = performance.now()
            testSpliceStringPerformance(s2, repeatTimes)
            end = performance.now()
            var splicePerf = end - start

            console.log(
                "string size           =", "Some String ".length * actualStringSize, "\n",
                "repeat count          = ", repeatTimes, "\n",
                "splice performance    = ", splicePerf, "\n",
                "substring performance = ", subStrPerf, "\n",
                "difference = ", splicePerf - subStrPerf  // + = splice is faster, - = subStr is faster
                )

        }
    }
}

doTests(1, 100)

性能上的一般差异充其量是微不足道的,并且两种方法都可以正常工作(即使在长度约为〜12000000的字符串上)


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.