Comment puis-je insérer une chaîne à un index spécifique d'une autre chaîne?
var txt1 = "foo baz"
Supposons que je veuille insérer "bar" après le "foo", comment puis-je atteindre cet objectif?
J'ai pensé à substring()
, mais il doit y avoir un chemin plus simple, plus simple.
Vous pouvez prototyper votre propre splice()
dans String.
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"
EDIT: Modifié pour que rem
soit une valeur absolue.
L'insertion à un index spécifique (plutôt que, par exemple, au premier caractère d'espacement) doit utiliser le découpage en chaîne/sous-chaîne:
var txt2 = txt1.slice(0, 3) + "bar" + txt1.slice(3);
Essaye ça. Voici une méthode que j'ai écrite et qui se comporte comme toutes les autres langues de programmation.
String.prototype.insert = function (index, string) {
if (index > 0)
return this.substring(0, index) + string + this.substring(index, this.length);
return string + this;
};
Exemple d'utilisation:
var something = "How you?";
something = something.insert(3, " are");
Simples.
Référence: http://coderamblings.wordpress.com/2012/07/09/insert-a-string-at-a-specific-index/
Il suffit de faire la fonction suivante:
function insert(str, index, value) {
return str.substr(0, index) + value + str.substr(index);
}
et ensuite l'utiliser comme ça:
alert(insert("foo baz", 4, "bar "));
sortie: foo bar baz
Il se comporte exactement comme le C # (Sharp) String.Insert (int startIndex, valeur de chaîne).
NOTE: Cette fonction d'insertion insère la chaîne valeur (troisième paramètre) avant l'entier spécifié index (deuxième paramètre) dans la chaîne str (premier paramètre), puis renvoie la nouvelle chaîne sans changer str!
MISE À JOUR 2016: Voici une autre fonction de prototype juste pour le plaisir (mais plus grave!) Basée sur une doublure - RegExp
approche (avec un support standard sur undefined
ou négatif 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"
Précédent (retour en 2012) juste pour le plaisir solution:
var index = 4,
what = 'bar ';
'foo baz'.replace(/./g, function(v, i) {
return i === index - 1 ? v + what : v;
}); // "foo bar baz"
C’est essentiellement ce que fait @ Bass33, sauf que je donne également la possibilité d’utiliser un index négatif pour compter à partir de la fin. Un peu comme la méthode substr permet.
// 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);
};
Cas d'utilisation: disons que vous avez des images en taille réelle utilisant une convention de dénomination, mais que vous ne pouvez pas mettre à jour les données afin de fournir également des URL de vignettes.
var url = '/images/myimage.jpg';
var thumb = url.insert(-4, '_thm');
// result: '/images/myimage_thm.jpg'
Si quelqu'un cherche un moyen d'insérer du texte à plusieurs index dans une chaîne, essayez ceci:
String.prototype.insertTextAtIndices = function(text) {
return this.replace(/./g, function(character, index) {
return text[index] ? text[index] + character : character;
});
};
Par exemple, vous pouvez utiliser ceci pour insérer des balises <span>
à certains décalages d'une chaîne:
var text = {
6: "<span>",
11: "</span>"
};
"Hello world!".insertTextAtIndices(text); // returns "Hello <span>world</span>!"
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('');
Compte tenu de votre exemple actuel, vous pouvez obtenir le résultat en:
var txt2 = txt1.split(' ').join(' bar ')
ou
var txt2 = txt1.replace(' ', ' bar ');
mais étant donné que vous pouvez faire de telles hypothèses, vous pouvez également passer directement à l'exemple de Gullen.
Dans une situation où vous ne pouvez vraiment pas faire d'hypothèses autres que celles basées sur un index de caractères, j'opterais vraiment pour une solution de sous-chaîne.
function insertString(string, insertion, place) {
return string.replace(string[place] + string[place + 1], string[place] + insertion + string[place + 1])
}
Donc, pour vous, ce serait insertString("foo baz", "bar", 3);
Évidemment, ce serait une peinture à utiliser parce que vous devez fournir votre chaîne à la fonction à chaque fois, mais pour le moment, je ne sais pas comment en faire quelque chose de plus simple, comme un string.replace(insertion, place)
. L'idée est toujours valable.
Je sais que c'est un vieux fil, cependant, voici une approche vraiment efficace.
var tn = document.createTextNode("I am just to help")
t.insertData(10, "trying");
Ce qui est formidable, c’est que le contenu du nœud est forcé. Ainsi, si ce nœud se trouvait déjà dans le DOM, vous n’auriez pas besoin d’utiliser de sélecteurs de requête ni de mettre à jour le innerText. Les changements seraient dus à sa liaison.
Si vous aviez besoin d'une chaîne, accédez simplement à la propriété de contenu textuel du nœud.
tn.textContent
#=> "I am just trying to help"
Vous pouvez utiliser des expressions régulières avec un motif dynamique.
var text = "something";
var output = " ";
var pattern = new RegExp("^\\s{"+text.length+"}");
var output.replace(pattern,text);
les sorties:
"something "
Ceci remplace text.length
des caractères d'espacement au début de la chaîne output
. La RegExp
signifie ^\
- le début d'une ligne \s
tout caractère blanc, répété {n}
fois, dans ce cas text.length
. Utilisez \\
pour \
échapper aux barres obliques inverses lors de la création de ce type de modèle à partir de chaînes.
une autre solution, couper la chaîne en 2 et mettre une chaîne entre les deux.
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);
Nous pouvons utiliser à la fois la méthode de la sous-chaîne et de la méthode 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
Le seul problème d'une méthode de sous-chaîne est qu'elle ne fonctionnera pas avec un index négatif. Il faut toujours prendre l'index de chaîne de la 0ème position.
Vous pouvez utiliser slice(0,index) + str + slice(index)
. Ou vous pouvez créer une méthode pour cela.
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
Vous pouvez split()
la chaîne principale et ajouter puis utiliser normal 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
La méthode prend un tableau de tableaux chaque élément de tableau représentant un seul 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"]]
]
))
Vous pouvez le faire facilement avec regex dans une ligne de code
const str = 'Hello RegExp!';
const index = 6;
const insert = 'Lovely ';
//'Hello RegExp!'.replace(/^(.{6})(.)/, `$1Lovely $2`);
str.replace(new RegExp(`^(.{${ index }})(.)`), `$1${ insert }$2`);
//< "Hello Lovely RegExp!"
Je voulais comparer la méthode utilisant la sous-chaîne et la méthode utilisant les tranches de Base33 et user113716 respectivement, pour ce faire, j'ai écrit du code.
regardez aussi ceci comparaison des performances, sous-chaîne, slice
Le code que j'ai utilisé crée d'énormes chaînes et insère plusieurs fois la chaîne "bar" dans la chaîne énorme
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)
La différence générale de performance est au mieux marginale et les deux méthodes fonctionnent très bien (même sur des chaînes de longueur ~ ~ 12000000)