แทรกสตริงที่ดัชนีเฉพาะ


333

ฉันจะแทรกสตริงที่ดัชนีเฉพาะของสตริงอื่นได้อย่างไร

 var txt1 = "foo baz"

สมมติว่าฉันต้องการแทรก "บาร์" หลังจาก "foo" ฉันจะบรรลุได้อย่างไร

ฉันคิดsubstring()แต่ต้องมีวิธีที่ง่ายกว่าตรงไปข้างหน้า


คำตอบ:


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วิธีการแก้ปัญหาด้านล่างดีกว่าและง่ายกว่า (Splice เป็นอันตรายไม่ชิ้นและจะดีกว่าเพื่อหลีกเลี่ยงการแก้ไข "วัตถุที่คุณไม่รู้จัก") วิธีแก้ปัญหานี้ไม่ควรเป็นคำตอบแรกที่มองเห็นได้อย่างชัดเจนแม้ว่ามันอาจจะสมเหตุสมผลก็ตาม
Eirik Birkeland

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)) นอกจากนี้ยังสั้นกว่าเล็กน้อยสำหรับราคาเพียงเล็กน้อย
Tim Down

8
ES6 เสนอทางเลือกที่ดีกว่านี้หรือไม่? อย่างน้อยสามารถใช้การแก้ไขสตริงเช่น`${txt1.slice(0,3)}bar${txt1.slice(3)}`
Jay

1
สิ่งนี้ไม่ได้ใช้ประโยชน์จากdeleteคุณสมบัติที่รวมอยู่ในข้างต้น คำตอบยอดนิยม ...
นาย Polywhirl

11
@ Mr.Polywhirl: ไม่คำถามไม่ได้กล่าวถึงว่าต้องทำเช่นนั้น
Tim Down

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 # (ชาร์ป) แทรก (int startIndex ค่าสตริง)

หมายเหตุ:ฟังก์ชั่นแทรกนี้จะแทรกค่าสตริง(พารามิเตอร์ที่สาม) ก่อนที่ดัชนีระบุจำนวนเต็ม(พารามิเตอร์ที่สอง) ในสตริงstr (พารามิเตอร์แรก) แล้วส่งกลับสตริงใหม่โดยไม่เปลี่ยนstr !


16

UPDATE 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

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

1
ใช่ฉันต้องการใช้ตัวแปรจำนวนเต็มเป็นการแทรกวิธีการทำงานของคุณ - ขอบคุณ - นี่คือสิ่งที่ฉันใช้ var a = 6; var b = 11; text = {}; text [a] = "xx"; text [b] = "yy"; - มีวิธีที่ดีกว่าในการเขียนว่า
Dex Dave

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

กรณีการใช้งาน: ให้บอกว่าคุณมีภาพขนาดเต็มโดยใช้หลักการตั้งชื่อ แต่ไม่สามารถอัปเดตข้อมูลเพื่อระบุ URL ขนาดย่อได้

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

เราสามารถใช้ทั้งวิธีย่อยและวิธีแบ่งย่อย

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

ปัญหาเดียวของวิธีการ substring คือมันจะไม่ทำงานกับดัชนีเชิงลบ มันมักจะใช้ดัชนีสตริงจากตำแหน่งที่ 0


AbsIndex stans ทำเพื่ออะไร
Enrique Bermúdez

Btw ขอบคุณสำหรับวิธีที่สอง มันใช้งานได้เหมือนมีเสน่ห์!
Enrique Bermú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 หมาย- จุดเริ่มต้นของเส้นอักขระช่องว่างใด ๆ สีขาวซ้ำแล้วซ้ำอีกครั้งในกรณีนี้ ใช้เพื่อหลีกเลี่ยงแบ็กสแลชเมื่อสร้างรูปแบบชนิดนี้จากสตริง outputRegExp^\\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);

"สวัสดี Lovely 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

วิธีการ Splice สำหรับเงื่อนไข

คุณสามารถ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()วิธีการที่ใช้อาร์เรย์ของอาร์เรย์องค์ประกอบของอาร์เรย์เป็นตัวแทนของแต่ละเดียว

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 ตามลำดับเพื่อที่ฉันเขียนโค้ดบางส่วน

ยังได้ดูที่การเปรียบเทียบประสิทธิภาพการทำงานย่อยสตริงชิ้นนี้

รหัสที่ฉันใช้สร้างสตริงขนาดใหญ่และแทรกสตริง "บาร์" หลาย ๆ ครั้งลงในสตริงขนาดใหญ่

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)


0
  1. ยกตัวอย่างอาร์เรย์จากสตริง
  2. ใช้Array # splice
  3. Stringify อีกครั้งโดยใช้Array # เข้าร่วม

ประโยชน์ของวิธีนี้คือสองเท่า:

  1. ง่าย
  2. สอดคล้องกับจุดโค้ด Unicode

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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.