【问题标题】:Insert a string at a specific index在特定索引处插入字符串
【发布时间】:2011-05-17 20:43:17
【问题描述】:

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

 var txt1 = "foo baz"

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

我想到了substring(),但肯定有更简单更直接的方法。

【问题讨论】:

标签: javascript string


【解决方案1】:

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

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

【讨论】:

  • @AlejandroSalamancaMazuelo:substring 在这里会很好。我一般更喜欢slice,因为它更灵活(负索引,例如"foo baz".slice(1, -2))。它也稍微短一些,因为它是值得的。
  • ES6 是否提供了更好的选择?至少可以使用字符串插值,比如`${txt1.slice(0,3)}bar${txt1.slice(3)}`
  • 这没有利用 above; top answer 中包含的 delete 功能...
  • @Mr.Polywhirl:不。这个问题没有提到需要这样做。
【解决方案2】:

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

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

【讨论】:

  • 我知道这是从 2010 年开始的,但下面的 slice 解决方案更好更简单。 (拼接是破坏性的,切片不是,最好避免修改“你不知道的对象”)。这个解决方案绝对不应该是第一个可见的答案,即使它在当时可能是有意义的。
  • @EirikBirkeland:字符串是不可变的。上面的代码没有修改任何对象。无论哪种方式,您不修改 "objects you don't know" 的想法都会排除 Array 变异方法。你说你宁愿做my_array[my_array.length] = item而不是my_array.push(item)
  • 对不起,我的意思是“你不拥有的对象”。在这种情况下,您对splice 的看法是正确的;确实字符串是不可变的。出于这个原因,我认为splice 是一个糟糕的关键词选择。我的主要反对意见是反对任意扩展原型,除非它们是标准的 polyfill。
  • 修改内置对象是难以置信的坏习惯。正如我们在SmooshGate 中看到的那样,随着新功能被添加到语言中,这可能会破坏您的代码,并且如果您的不负责任的修改以某种方式进入了一个在网络上被广泛采用的库,它可能会阻止使用简单、清晰的新功能的方法名称。
【解决方案3】:

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

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

  return string + this;
};

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

参考:

【讨论】:

  • 您可能需要在 if-else 块中添加花括号 {}
  • 不,不需要。但是else 是多余的。
【解决方案4】:

只需执行以下功能:

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) 完全一样。

注意:这个插入函数插入字符串value(第三个参数)before指定的整数index(第二个参数)在字符串str(第一个参数)中,然后在不改变str的情况下返回新的字符串!

【讨论】:

    【解决方案5】:

    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"
    

    【讨论】:

    • 如果您需要在字符串的多个索引处插入文本,这也很棒。如果是这种情况,请参阅下面的答案。
    【解决方案6】:

    如果有人正在寻找一种在字符串的多个索引处插入文本的方法,试试这个:

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

    【讨论】:

    • 我尝试了这种方法,但是用变量替换了 '6' 和 '11' 它不起作用 - 我做错了什么 - 请帮助。在此先感谢:)
    • 6 和 11 是将文本插入字符串的索引。 6: "&lt;span&gt;" 说:在索引 6 处,插入文本“”。您是说要使用整数变量的值作为插入索引吗?如果是这种情况,请尝试var a=6, text = {}; text[a] = "&lt;span&gt;";
    • 是的,我想使用整数变量作为插入,你的方法有效 - 谢谢你 - 这就是我使用的 var a=6;变量 b=11;文本 = {};文本[a] = "xx";文本[b] = "yy"; - 有没有更好的方法来写呢
    【解决方案7】:

    这基本上是在做@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);
    };
    

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

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

    【讨论】:

      【解决方案8】:

      鉴于您当前的示例,您可以通过以下任一方式实现结果

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

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

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

      在除了基于字符索引之外你真的无法做出任何假设的情况下,我真的会选择子字符串解决方案。

      【讨论】:

        【解决方案9】:
        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/

        【讨论】:

          【解决方案10】:
          1. 从字符串实例化一个数组
          2. 使用Array#splice
          3. 使用Array#join 再次进行字符串化

          这种方法的好处有两个:

          1. 简单
          2. Unicode 码位兼容

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

          【讨论】:

          • 这实际上是一个非常简单的解决方案,我会说这里是最好的选择,您也可以内联它,但可以按原样使用。
          【解决方案11】:

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

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

          这样做的好处是它强制节点内容。所以如果这个节点已经在 DOM 上,你就不需要使用任何查询选择器或更新 innerText。由于其绑定,这些更改将反映出来。

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

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

          【讨论】:

            【解决方案12】:

            好吧,我们可以同时使用 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.substr(index);
            
                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 代表什么?
            • 顺便说一句,感谢第二种方法。它就像一个魅力!
            【解决方案13】:

            您可以使用具有动态模式的正则表达式。

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

            输出:

            "something      "
            

            这将替换字符串output 开头的空白字符text.lengthRegExp 表示 ^\ - 行的开头 \s 任何空白字符,重复 {n} 次,在本例中为 text.length。从字符串构建这种模式时,使用\\\ 转义反斜杠。

            【讨论】:

              【解决方案14】:

              你可以在一行代码中使用正则表达式轻松完成

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

              “你好可爱的正则表达式!”

              【讨论】:

                【解决方案15】:

                另一种解决方案,将字符串剪成 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);
                

                【讨论】:

                  【解决方案16】:

                  使用切片

                  您可以使用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"]]
                  ]
                  
                  ))

                  【讨论】:

                    【解决方案17】:

                    我想分别比较使用 substring 的方法和使用来自 Base33 和 user113716 的 slice 的方法,为此我写了一些代码

                    也看看这个performance comparison, substring, 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 的字符串上)

                    【讨论】:

                      【解决方案18】:

                      采取解决方案。我以简单的格式编写了这段代码:

                      const insertWord = (sentence,word,index) => {
                          var sliceWord = word.slice(""),output = [],join; // Slicing the input word and declaring other variables
                          var sliceSentence = sentence.slice(""); // Slicing the input sentence into each alphabets
                          for (var i = 0; i < sliceSentence.length; i++) 
                                 {
                              if (i === index) 
                                     { // checking if index of array === input index
                                  for (var j = 0; j < word.length; j++) 
                                             {   // if yes we'll insert the word
                                      output.push(sliceWord[j]); // Condition is true we are inserting the word
                                             }
                                  output.push(" "); // providing a single space at the end of the word
                                       }
                              output.push(sliceSentence[i]);  // pushing the remaining elements present in an array
                                  }
                          join = output.join(""); // converting an array to string
                          console.log(join)
                          return join;
                      }
                      

                      【讨论】:

                        【解决方案19】:

                        使用 ramda:

                        import { pipe, split, insert, join } from 'ramda';
                        
                        const insertAtIndex = (strToInsert, index, str) => 
                          pipe(split(''), insert(index, strToInsert), join(''))(str)
                        

                        【讨论】:

                          猜你喜欢
                          • 2011-04-30
                          • 1970-01-01
                          • 2020-05-16
                          • 1970-01-01
                          • 2016-04-10
                          • 2019-07-03
                          • 1970-01-01
                          • 2011-10-20
                          相关资源
                          最近更新 更多