Como posso inserir uma string em um índice específico de outra string?
var txt1 = "foo baz"
Suponha que eu queira inserir "bar" após o "foo", como posso conseguir isso?
Pensei substring()
, mas deve haver uma maneira mais simples e direta.
Como posso inserir uma string em um índice específico de outra string?
var txt1 = "foo baz"
Suponha que eu queira inserir "bar" após o "foo", como posso conseguir isso?
Pensei substring()
, mas deve haver uma maneira mais simples e direta.
Respostas:
Você pode criar um protótipo splice()
para 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: Modificado para garantir que rem
seja um valor absoluto.
slice
solução abaixo é melhor e mais simples. (A emenda é destrutiva, a fatia não, e é melhor evitar modificar "objetos que você não conhece"). Esta solução absolutamente não deve ser a primeira resposta visível, mesmo que tenha feito sentido na época.
my_array[my_array.length] = item
vez de my_array.push(item)
?
splice
neste caso; de fato, as cordas são imutáveis. Por esse motivo, acho que splice
é uma má escolha de palavras-chave. Minha principal objeção é contra a extensão arbitrária de protótipos, a menos que sejam polyfills padrão.
A inserção em um índice específico (em vez de, digamos, no primeiro caractere de espaço) deve usar a segmentação / segmentação de sequência de caracteres:
var txt2 = txt1.slice(0, 3) + "bar" + txt1.slice(3);
substring
ficaria bem aqui. Eu prefiro slice
em geral porque é mais flexível (índices negativos, por exemplo "foo baz".slice(1, -2)
). Também é um pouco mais curto, pelo pouco que vale a pena.
`${txt1.slice(0,3)}bar${txt1.slice(3)}`
delete
recurso, conforme incluído acima; resposta superior ...
Aqui está um método que escrevi que se comporta como todas as outras linguagens de programação:
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)
{}
nos blocos if-else.
else
é redundante.
Basta fazer a seguinte função:
function insert(str, index, value) {
return str.substr(0, index) + value + str.substr(index);
}
e depois use-o assim:
alert(insert("foo baz", 4, "bar "));
Saída: foo bar baz
Ele se comporta exatamente, como o C # (Sharp) String.Insert (int startIndex, valor da string).
NOTA: Esta função de inserção insere o valor da string (terceiro parâmetro) antes do índice inteiro especificado (segundo parâmetro) na string str (primeiro parâmetro) e, em seguida, retorna a nova string sem alterar str !
ATUALIZAÇÃO 2016: Aqui está outra função de protótipo divertida (mas mais séria!) Baseada na RegExp
abordagem de uma linha (com suporte de prefix undefined
ou negativo 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"
Solução anterior (de volta a 2012) apenas por diversão :
var index = 4,
what = 'bar ';
'foo baz'.replace(/./g, function(v, i) {
return i === index - 1 ? v + what : v;
}); // "foo bar baz"
Se alguém estiver procurando uma maneira de inserir texto em vários índices em uma string, tente o seguinte:
String.prototype.insertTextAtIndices = function(text) {
return this.replace(/./g, function(character, index) {
return text[index] ? text[index] + character : character;
});
};
Por exemplo, você pode usar isso para inserir <span>
tags em certas compensações em uma string:
var text = {
6: "<span>",
11: "</span>"
};
"Hello world!".insertTextAtIndices(text); // returns "Hello <span>world</span>!"
6: "<span>"
diz: no índice 6, insira o texto "<span>". Você está dizendo que deseja usar o valor de uma variável inteira como índice de inserção? Se for esse o caso, tente algo comovar a=6, text = {}; text[a] = "<span>";
Isso é basicamente fazer o que @ Bass33 está fazendo, exceto que eu também estou dando a opção de usar um índice negativo para contar a partir do final. Como o método substr permite.
// 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);
};
Caso de uso: digamos que você tenha imagens em tamanho real usando uma convenção de nomenclatura, mas não pode atualizar os dados para também fornecer URLs em miniatura.
var url = '/images/myimage.jpg';
var thumb = url.insert(-4, '_thm');
// result: '/images/myimage_thm.jpg'
Dado o seu exemplo atual, você pode obter o resultado quer
var txt2 = txt1.split(' ').join(' bar ')
ou
var txt2 = txt1.replace(' ', ' bar ');
mas, como você pode fazer essas suposições, você também pode pular diretamente para o exemplo de Gullen.
Em uma situação em que você realmente não pode fazer nenhuma suposição que não seja baseada no índice de caracteres, eu realmente procuraria uma solução de substring.
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('');
Eu sei que este é um tópico antigo, no entanto, aqui está uma abordagem realmente eficaz.
var tn = document.createTextNode("I am just to help")
t.insertData(10, "trying");
O que é ótimo nisso é que ele coage o conteúdo do nó. Portanto, se esse nó já estivesse no DOM, você não precisaria usar nenhum seletor de consulta ou atualizar o innerText. As alterações refletiriam devido à sua ligação.
Se você precisar de uma sequência, basta acessar a propriedade de conteúdo de texto do nó.
tn.textContent
#=> "I am just trying to help"
Bem, podemos usar os métodos substring e 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
O único problema de um método de substring é que ele não funcionará com um índice negativo. É sempre pegar o índice de string da 0ª posição.
function insertString(string, insertion, place) {
return string.replace(string[place] + string[place + 1], string[place] + insertion + string[place + 1])
}
Então, para você, seria insertString("foo baz", "bar", 3);
Obviamente, isso seria uma tinta para usar, porque você precisa fornecer sua string para a função todas as vezes, mas no momento não sei como torná-la algo mais fácil, como a string.replace(insertion, place)
. A idéia ainda permanece, no entanto.
Você pode usar expressões regulares com um padrão dinâmico .
var text = "something";
var output = " ";
var pattern = new RegExp("^\\s{"+text.length+"}");
var output.replace(pattern,text);
saídas:
"something "
Isso substitui os text.length
caracteres de espaço em branco no início da string output
. Os RegExp
meios ^\
- início de uma linha, \s
qualquer caractere de espaço em branco, repetidas {n}
vezes, neste caso text.length
. Use \\
para \
escapar de barras invertidas ao criar esse tipo de padrão a partir de strings.
outra solução, corte a corda em 2 e coloque-a no meio.
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);
Você pode fazer isso facilmente com regexp em uma linha de código
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);
"Olá, adorável RegExp!"
Você pode usar slice(0,index) + str + slice(index)
. Ou você pode criar um método para isso.
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
Você pode split()
a string principal e adicionar e usar o normalsplice()
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
O método utiliza uma matriz de matrizes, cada elemento da matriz representando um único 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"]]
]
))
Eu queria comparar o método usando substring e o método usando slice da Base33 e user113716 respectivamente, para fazer isso, escrevi algum código
também dê uma olhada nessa comparação de desempenho, substring, fatia
O código que eu usei cria cadeias enormes e insere a "barra" da cadeia várias vezes na cadeia enorme
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)
A diferença geral de desempenho é marginal, na melhor das hipóteses, e ambos os métodos funcionam muito bem (mesmo em cadeias de comprimento ~~ 12000000)
Os benefícios dessa abordagem são duplos:
const pair = Array.from('USDGBP')
pair.splice(3, 0, '/')
console.log(pair.join(''))