Fügen Sie eine Zeichenfolge an einem bestimmten Index ein

332

Wie kann ich eine Zeichenfolge an einem bestimmten Index einer anderen Zeichenfolge einfügen?

 var txt1 = "foo baz"

Angenommen, ich möchte nach dem "foo" "bar" einfügen. Wie kann ich das erreichen?

Ich dachte daran substring(), aber es muss einen einfacheren und direkteren Weg geben.

Jiew Meng
quelle

Antworten:

257

Sie könnten Ihren eigenen Prototyp splice()in String erstellen.

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

Beispiel

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"


BEARBEITEN: Es wurde geändert, um sicherzustellen, dass dies remein absoluter Wert ist.

user113716
quelle
6
Ich weiß, dass dies aus dem Jahr 2010 stammt, aber die folgende sliceLösung ist besser und einfacher. (Splice ist destruktiv, Slice nicht, und es ist besser zu vermeiden, "Objekte, die Sie nicht kennen" zu ändern.) Diese Lösung sollte absolut nicht die erste sichtbare Antwort sein, auch wenn sie zu diesem Zeitpunkt möglicherweise sinnvoll war.
Eirik Birkeland
6
@EirikBirkeland: Strings sind unveränderlich. Der obige Code ändert kein Objekt. In jedem Fall würde Ihre Vorstellung, "Objekte, die Sie nicht kennen " nicht zu ändern, Array-Mutationsmethoden ausschließen. Sie sagen, Sie würden es lieber tun my_array[my_array.length] = itemals my_array.push(item)?
4
Entschuldigung, ich meinte "Objekte, die Sie nicht besitzen". spliceIn diesem Fall haben Sie Recht . in der Tat sind Saiten unveränderlich. Aus diesem Grund halte ich es jedoch für spliceeine schlechte Schlüsselwortwahl. Mein Hauptargument ist, Prototypen willkürlich zu erweitern, es sei denn, es handelt sich um Standard-Polyfills.
Eirik Birkeland
1
Es ist unglaublich schlecht, eingebaute Objekte zu modifizieren. Wie wir bei SmooshGate gesehen haben , besteht die Gefahr, dass Ihr Code beschädigt wird , wenn der Sprache neue Funktionen hinzugefügt werden. Sollte Ihre unverantwortliche Änderung in eine Bibliothek gelangen, die im gesamten Web eine erhebliche Akzeptanz findet, kann die Verwendung eines einfachen, klaren Methodennamens blockiert werden für neue Funktionen.
Sean
401

Das Einfügen an einem bestimmten Index (anstatt beispielsweise am ersten Leerzeichen) muss String Slicing / Teilstring verwenden:

var txt2 = txt1.slice(0, 3) + "bar" + txt1.slice(3);
Tim Down
quelle
4
@AlejandroSalamancaMazuelo: substringwäre hier in Ordnung. Ich bevorzuge sliceim Allgemeinen, weil es flexibler ist (z "foo baz".slice(1, -2). B. negative Indizes ). Es ist auch etwas kürzer, für die kleinen, die es wert sind.
Tim Down
8
Bietet ES6 eine bessere Alternative? Könnte zumindest String-Interpolation verwenden, wie`${txt1.slice(0,3)}bar${txt1.slice(3)}`
Jay
1
Hierbei wird die oben beschriebene deleteFunktion nicht verwendet . Top-Antwort ...
Mr. Polywhirl
11
@ Mr.Polywhirl: Nein. In der Frage wird nicht erwähnt, dass dies erforderlich ist.
Tim Down
133

Hier ist eine Methode, die ich geschrieben habe und die sich wie alle anderen Programmiersprachen verhält:

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)

Referenz:

Base33
quelle
1
Möglicherweise müssen Sie {}den if-else-Blöcken geschweifte Klammern hinzufügen .
Mr-IDE
3
Nein, muss nicht. Aber das elseist überflüssig.
Bitterblue
72

Machen Sie einfach die folgende Funktion:

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

und dann benutze es so:

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

Ausgabe: foo bar baz

Es verhält sich genau wie der C # (Sharp) String.Insert (int startIndex, String-Wert).

HINWEIS: Diese Insert - Funktion fügt der String - Wert (dritte Parameter) vor dem angegebenen Integer - Index (zweiter Parameter) im String str (erster Parameter), und dann die neue Zeichenfolge zurück ohne Änderung str !


quelle
16

UPDATE 2016: Hier ist eine weitere nur zum Spaß (aber ernsthafter!) Prototypfunktion, die auf einem Einzeiler- RegExpAnsatz basiert (mit aktivierter undefinedoder negativer Unterstützung im Vorfeld 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"

Vorherige (zurück bis 2012) Just-for-Fun- Lösung:

var index = 4,
    what  = 'bar ';

'foo baz'.replace(/./g, function(v, i) {
    return i === index - 1 ? v + what : v;
});  // "foo bar baz"
Vision
quelle
1
Dies ist auch hilfreich, wenn Sie Text an mehreren Indizes in eine Zeichenfolge einfügen müssen. Siehe meine Antwort unten, wenn dies der Fall ist.
Jake Stoeffler
12

Wenn jemand nach einer Möglichkeit sucht, Text an mehreren Indizes in eine Zeichenfolge einzufügen, probieren Sie Folgendes aus:

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

Sie können dies beispielsweise verwenden, um <span>Tags an bestimmten Offsets in eine Zeichenfolge einzufügen :

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

"Hello world!".insertTextAtIndices(text); // returns "Hello <span>world</span>!"
Jake Stoeffler
quelle
1
Ich habe diese Methode ausprobiert, aber '6' und '11' durch Variablen ersetzt, die nicht funktionieren - was mache ich falsch - bitte helfen. Vielen Dank im Voraus :)
Dex Dave
1
6 und 11 sind die Indizes, an denen der Text in die Zeichenfolge eingefügt wird. 6: "<span>"sagt: Geben Sie bei Index 6 den Text "<span>" ein. Wollen Sie damit sagen, dass Sie den Wert einer Ganzzahlvariablen als Einfügeindex verwenden möchten? Wenn das der Fall ist, versuchen Sie etwas wievar a=6, text = {}; text[a] = "<span>";
Jake Stoeffler
1
Ja, ich möchte ganzzahlige Variablen als Einfügung verwenden. Ihre Methode hat funktioniert. Danke. Dies ist, was ich verwendet habe. var a = 6; var b = 11; text = {}; text [a] = "xx"; text [b] = "yy"; - Gibt es eine bessere Möglichkeit, das zu schreiben?
Dex Dave
11

Dies ist im Grunde das, was @ Bass33 tut, außer dass ich auch die Option gebe, einen negativen Index zu verwenden, um vom Ende an zu zählen. Ein bisschen wie es die substr-Methode erlaubt.

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

Anwendungsfall: Nehmen wir an, Sie haben Bilder in voller Größe unter Verwendung einer Namenskonvention, können die Daten jedoch nicht aktualisieren, um auch Miniaturansichten für Miniaturansichten bereitzustellen.

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

//    result:  '/images/myimage_thm.jpg'
Ryan Ore
quelle
9

Anhand Ihres aktuellen Beispiels könnten Sie das Ergebnis entweder durch erzielen

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

oder

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

Da Sie jedoch solche Annahmen treffen können, können Sie auch direkt zu Gullens Beispiel springen.

In einer Situation, in der Sie wirklich keine anderen Annahmen als zeichenindexbasiert treffen können, würde ich mich wirklich für eine Teilstring-Lösung entscheiden.

David Hedlund
quelle
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/

user40521
quelle
6

Ich weiß, dass dies ein alter Thread ist, aber hier ist ein wirklich effektiver Ansatz.

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

Das Schöne daran ist, dass es den Knoteninhalt erzwingt. Wenn sich dieser Knoten bereits im DOM befindet, müssen Sie keine Abfrageselektoren verwenden oder den innerText aktualisieren. Die Änderungen würden sich aufgrund ihrer Bindung widerspiegeln.

Wenn Sie eine Zeichenfolge benötigen, greifen Sie einfach auf die Textinhalteigenschaft des Knotens zu.

tn.textContent
#=> "I am just trying to help"
Sebastian Scholl
quelle
6

Nun, wir können sowohl die Teilstring- als auch die Slice-Methode verwenden.

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

Das einzige Problem einer Teilstring-Methode ist, dass sie mit einem negativen Index nicht funktioniert. Es wird immer der String-Index von der 0. Position genommen.

Kamal
quelle
Wofür steht absIndex?
Enrique Bermúdez
Übrigens, danke für die zweite Methode. Es wirkt wie ein Zauber!
Enrique Bermúdez
5
function insertString(string, insertion, place) {
  return string.replace(string[place] + string[place + 1], string[place] + insertion + string[place + 1])
}

Für Sie wäre es also so insertString("foo baz", "bar", 3);

Natürlich wäre dies eine Farbe, die Sie verwenden müssen, da Sie der Funktion jedes Mal Ihre Zeichenfolge zuweisen müssen, aber im Moment weiß ich nicht, wie ich es zu etwas Einfacherem wie einem machen kann string.replace(insertion, place). Die Idee bleibt jedoch bestehen.

Quelklef
quelle
4

Sie können reguläre Ausdrücke mit einem dynamischen Muster verwenden.

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

Ausgänge:

"something      "

Dies ersetzt text.lengthLeerzeichen am Anfang der Zeichenfolge output. Das RegExpbedeutet ^\- Zeilenanfang ein \sbeliebiges Leerzeichen {n}, in diesem Fall mehrmals wiederholt text.length. Verwenden Sie diese Option \\, \um Backslashes zu vermeiden, wenn Sie diese Art von Mustern aus Zeichenfolgen erstellen.

Nicht funktionsfähig
quelle
3

eine andere Lösung, schneiden Sie die Schnur in 2 und legen Sie eine Schnur dazwischen.

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);
Schlammhai2005
quelle
3

Sie können dies problemlos mit regulärem Ausdruck in einer Codezeile tun

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

"Hallo schöne RegExp!"

Madmadi
quelle
2

Slice verwenden

Sie können verwenden slice(0,index) + str + slice(index). Oder Sie können eine Methode dafür erstellen.

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

Spleißmethode für Strings

Sie können split()die Hauptzeichenfolge hinzufügen und dann normal verwendensplice()

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

Anwenden von splice () auf mehrere Indizes

Die Methode verwendet ein Array von Arrays, wobei jedes Element des Arrays ein einzelnes darstellt 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"]]
]

))

Maheer Ali
quelle
1

Ich wollte die Methode mit Teilzeichenfolge und die Methode mit Slice von Base33 bzw. user113716 vergleichen, um dies zu tun, schrieb ich etwas Code

Schauen Sie sich auch diesen Leistungsvergleich an, Teilzeichenfolge, Slice

Der von mir verwendete Code erstellt große Zeichenfolgen und fügt die Zeichenfolge "bar" mehrmals in die große Zeichenfolge ein

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)

Der allgemeine Leistungsunterschied ist bestenfalls gering und beide Methoden funktionieren einwandfrei (auch bei Saiten mit einer Länge von ~ ~ 12000000).

Pierre
quelle
0
  1. Instanziieren Sie ein Array aus der Zeichenfolge
  2. Verwenden Sie Array # splice
  3. Stringify erneut mit Array # join

Dieser Ansatz bietet zwei Vorteile:

  1. Einfach
  2. Unicode-Codepunkt-konform

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

Ben Aston
quelle