Chèn một chuỗi tại một chỉ mục cụ thể


332

Làm cách nào tôi có thể chèn một chuỗi tại một chỉ mục cụ thể của một chuỗi khác?

 var txt1 = "foo baz"

Giả sử tôi muốn chèn "thanh" sau "foo", làm thế nào tôi có thể đạt được điều đó?

Tôi nghĩ substring(), nhưng phải có một cách đơn giản hơn về phía trước.


Câu trả lời:


257

Bạn có thể tạo nguyên mẫu của riêng bạn splice()thành Chuỗi.

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

Thí dụ

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"


EDIT: Sửa đổi nó để đảm bảo đó remlà một giá trị tuyệt đối.


6
Tôi biết điều này là từ năm 2010, nhưng slicegiải pháp dưới đây là tốt hơn và đơn giản hơn. (Splice là phá hoại, lát cắt không, và tốt hơn là tránh sửa đổi "các đối tượng bạn không biết"). Giải pháp này tuyệt đối không nên là câu trả lời hữu hình đầu tiên, mặc dù nó có thể có ý nghĩa vào thời điểm đó.
Eirik Birkeland

6
@EirikBirkeland: Chuỗi là bất biến. Đoạn mã trên không sửa đổi bất kỳ đối tượng nào. Dù bằng cách nào, khái niệm của bạn về việc không sửa đổi "các đối tượng bạn không biết " sẽ loại trừ các phương thức đột biến Mảng. Bạn nói rằng bạn muốn làm my_array[my_array.length] = itemthay vì my_array.push(item)?

4
Xin lỗi tôi có nghĩa là "đối tượng bạn không SỞ HỮU". Bạn đúng về splicetrường hợp này; thực sự chuỗi là bất biến. Vì lý do này, tôi nghĩ splicelà một sự lựa chọn từ khóa kém. Phản đối chính của tôi là chống lại việc mở rộng các nguyên mẫu tùy ý, trừ khi chúng là các polyfill tiêu chuẩn.
Eirik Birkeland

1
Đó là thực tế cực kỳ xấu để sửa đổi một đối tượng tích hợp. Như chúng ta đã thấy với SmooshGate , rủi ro này phá vỡ mã của bạn khi chức năng mới được thêm vào ngôn ngữ và, nếu sửa đổi vô trách nhiệm của bạn bằng cách nào đó vào một thư viện thấy sự hấp thụ đáng kể trên web, nó có thể chặn việc sử dụng tên phương thức đơn giản, rõ ràng cho chức năng mới.
Sean

401

Chèn vào một chỉ mục cụ thể (chứ không phải là, ở ký tự khoảng trắng đầu tiên) phải sử dụng chuỗi cắt / chuỗi con:

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

4
@AlejandroSalamancaMazuelo: substringsẽ ổn ở đây. Tôi thích slicenói chung vì nó linh hoạt hơn (chỉ số tiêu cực, ví dụ "foo baz".slice(1, -2)). Nó cũng ngắn hơn một chút, với giá trị nhỏ.
Tim Down

8
ES6 có cung cấp một sự thay thế tốt hơn không? Ít nhất có thể sử dụng phép nội suy chuỗi, như`${txt1.slice(0,3)}bar${txt1.slice(3)}`
Jay

1
Điều này không sử dụng các deletetính năng như bao gồm ở trên; câu trả lời hàng đầu ...
Ông Polywhirl

11
@ Mr.Polywhirl: Không. Câu hỏi không đề cập đến việc cần phải làm điều đó.
Tim Down

133

Đây là một phương pháp tôi đã viết giống như tất cả các ngôn ngữ lập trình khác:

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)

Tài liệu tham khảo:


1
Bạn có thể cần thêm dấu ngoặc nhọn {}vào các khối if-other.
Mr-IDE

3
Không, không cần. Nhưng elselà dư thừa.
Bitterblue

72

Chỉ cần thực hiện các chức năng sau:

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

và sau đó sử dụng nó như thế:

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

Đầu ra: thanh foo

Nó hoạt động chính xác, như Chuỗi C # (Sắc nét) .Insert (int start Index, giá trị chuỗi).

Chú ý: Đây chèn chức năng chèn chuỗi giá trị (tham số thứ ba) trước khi các số nguyên xác định chỉ số (tham số thứ hai) trong chuỗi str (tham số đầu tiên), và sau đó trả về chuỗi mới mà không thay đổi str !


16

CẬP NHẬT 2016: Đây là một chức năng nguyên mẫu chỉ dành cho vui (nhưng nghiêm trọng hơn!) Dựa trên RegExpphương pháp một lớp (có hỗ trợ trả trước undefinedhoặc phủ định 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"

Trước đó (trở lại năm 2012) chỉ để giải trí:

var index = 4,
    what  = 'bar ';

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

1
Điều này cũng tuyệt vời nếu bạn cần chèn văn bản tại nhiều chỉ mục trong một chuỗi. Xem câu trả lời của tôi dưới đây nếu đó là trường hợp.
Jake Stoeffler

12

Nếu bất cứ ai đang tìm cách chèn văn bản tại nhiều chỉ mục trong một chuỗi, hãy thử điều này:

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

Ví dụ: bạn có thể sử dụng điều này để chèn <span>thẻ tại một số độ lệch nhất định trong chuỗi:

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

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

1
Tôi đã thử phương pháp này nhưng thay thế '6' và '11' bằng các biến không hoạt động - tôi đang làm gì sai - xin vui lòng giúp đỡ. Cảm ơn trước :)
Dex Dave

1
6 và 11 là các chỉ số mà tại đó văn bản sẽ được chèn vào chuỗi. 6: "<span>"nói: tại chỉ mục 6, chèn văn bản "<span>". Bạn đang nói rằng bạn muốn sử dụng giá trị của một biến số nguyên làm chỉ số chèn? Nếu đó là trường hợp, hãy thử một cái gì đó nhưvar a=6, text = {}; text[a] = "<span>";
Jake Stoeffler

1
yea Tôi muốn sử dụng các biến số nguyên làm phần chèn, phương thức của bạn đã hoạt động - cảm ơn bạn - đây là những gì tôi đã sử dụng var a = 6; var b = 11; văn bản = {}; văn bản [a] = "xx"; văn bản [b] = "yy"; - có cách nào tốt hơn để viết điều đó không
Dex Dave

11

Điều này về cơ bản là làm những gì @ Bass33 đang làm ngoại trừ tôi cũng đưa ra tùy chọn sử dụng chỉ số âm để đếm từ cuối. Kiểu như phương pháp cơ chất cho phép.

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

Ca sử dụng: Hãy nói rằng bạn có hình ảnh kích thước đầy đủ bằng cách sử dụng quy ước đặt tên nhưng không thể cập nhật dữ liệu để cung cấp các url hình thu nhỏ.

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

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

9

Cho ví dụ hiện tại của bạn, bạn có thể đạt được kết quả bằng một trong hai

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

hoặc là

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

nhưng cho rằng bạn có thể đưa ra các giả định như vậy, bạn cũng có thể bỏ qua trực tiếp ví dụ của Gullen.

Trong tình huống mà bạn thực sự không thể đưa ra bất kỳ giả định nào ngoài việc dựa trên chỉ mục ký tự, thì tôi thực sự sẽ tìm giải pháp chuỗi con.



6

Tôi biết đây là một chủ đề cũ, tuy nhiên, đây là một cách tiếp cận thực sự hiệu quả.

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

Điều tuyệt vời ở đây là nó ép buộc nội dung nút. Vì vậy, nếu nút này đã có trên DOM, bạn sẽ không cần sử dụng bất kỳ bộ chọn truy vấn nào hoặc cập nhật phần bên trong. Những thay đổi sẽ phản ánh do ràng buộc của nó.

Bạn có cần một chuỗi không, chỉ cần truy cập thuộc tính nội dung văn bản của nút.

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

6

Vâng, chúng ta có thể sử dụng cả phương pháp chuỗi con và lát cắt.

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

Vấn đề duy nhất của phương pháp chuỗi con là nó sẽ không hoạt động với chỉ số âm. Nó luôn lấy chỉ số chuỗi từ vị trí 0.


Abs Index không dùng để làm gì?
Enrique Bermúdez

Btw, cảm ơn vì phương pháp thứ hai. Nó hoạt động như một say mê!
Enrique Bermúdez

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

Vì vậy, đối với bạn, nó sẽ là insertString("foo baz", "bar", 3);

Rõ ràng, đây sẽ là một loại sơn để sử dụng bởi vì bạn phải cung cấp chuỗi của mình cho hàm mỗi lần, nhưng hiện tại tôi không biết làm thế nào để biến nó thành một thứ dễ dàng hơn như a string.replace(insertion, place). Ý tưởng vẫn đứng, mặc dù.


4

Bạn có thể sử dụng Biểu thức chính quy với mẫu động .

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

đầu ra:

"something      "

Điều này thay thế text.lengthcác ký tự khoảng trắng ở đầu chuỗi output. Các RegExpphương tiện ^\- bắt đầu của một dòng \sbất kỳ ký tự khoảng trắng, lặp đi lặp lại {n}, trong trường hợp này text.length. Sử dụng \\để \thoát dấu gạch chéo ngược khi xây dựng kiểu mẫu này ra khỏi chuỗi.


3

một giải pháp khác, cắt chuỗi thành 2 và đặt một chuỗi ở giữa.

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

Bạn có thể làm điều đó một cách dễ dàng với biểu thức chính quy trong một dòng mã

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

"Xin chào RegExp đáng yêu!"


2

Sử dụng lát

Bạn có thể sử dụng slice(0,index) + str + slice(index). Hoặc bạn có thể tạo một phương thức cho nó.

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

Phương pháp mối nối cho chuỗi

Bạn có thể split()chuỗi chính và thêm sau đó sử dụng bình thườngsplice()

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

Áp dụng splice () tại nhiều chỉ mục

Phương thức này lấy một mảng các mảng, mỗi phần tử của mảng đại diện cho một mảng 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

Tôi muốn so sánh phương thức sử dụng chuỗi con và phương thức sử dụng lát cắt từ Base33 và user113716 tương ứng, để làm điều đó tôi đã viết một số mã

cũng có một cái nhìn về điều này so sánh hiệu suất , chuỗi con, lát

Mã tôi đã sử dụng tạo ra các chuỗi lớn và chèn chuỗi "thanh" nhiều lần vào chuỗi lớn

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)

Sự khác biệt chung về hiệu suất là tốt nhất và cả hai phương pháp đều hoạt động tốt (ngay cả trên các chuỗi có độ dài ~ ~ 12000000)


0
  1. Khởi tạo một mảng từ chuỗi
  2. Sử dụng mảng # mối nối
  3. Stringify một lần nữa bằng cách sử dụng Array # tham gia

Lợi ích của phương pháp này là hai lần:

  1. Đơn giản
  2. Tương thích điểm mã Unicode

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

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.