Chop / fatia / aparar JavaScript do último caractere na string


1974

Eu tenho uma string 12345.00e gostaria que ela retornasse 12345.0.

Eu olhei trim, mas parece que está apenas aparando espaços em branco e sliceque não vejo como isso funcionaria. Alguma sugestão?


36
Você se importa com arredondamentos? 12345.46 = 12345.5 ou 12345.4?
RSolberg 04/06/2009

9
Você sabe qual é o sufixo ou deseja dividir e remover a última palavra com base em seus sublinhados?
Cᴏʀʏ

65
Ho ho ho, @RSolberg: você não pode arredondar uma corda!
Ziggy #

50
@Ziggy diz o que? Math.round('0.5') === 1;)
TWiStErRob

16
@TWiStErRob Oh JavaScript, o que vou fazer com você? * balança a cabeça *
Chuck Le Butt

Respostas:


3214

Você pode usar a função de substring :

let str = "12345.00";
str = str.substring(0, str.length - 1);
console.log(str);

Esta é a resposta aceita, mas de acordo com as conversas abaixo, a sintaxe da fatia é muito mais clara:

let str = "12345.00";
str = str.slice(0, -1); 
console.log(str);


23
@Kheu - a notação de fatia é muito mais limpa para mim. Eu estava usando anteriormente a versão de substring. Obrigado!
Matt Bola

32
perdoe-me se eu estiver errado, mas você não precisa atribuir o valor de str.substring a str novamente? Comostr = str.substring(0, str.length -1);
Doug Molineux

10
Os métodos slice& substringsão todos iguais; excepto a que o slice()aceita um índice negativo, em relação ao fim da cadeia, mas não o substring, ele gera out-of-bounderro
Amol M Kulkarni

20
Caso alguém esteja se perguntando, substringé 11% mais rápido que slice. jsperf.com/js-slice-vs-substring-test
BenR

19
substring são micro-otimizações insanas que eu acho que você não deveria fazer. Maximize primeiro a legibilidade. Em seguida, otimize as frutas baixas, se necessário.
Alfred

1306

Você pode usar fatia ! Você só precisa ter certeza de que sabe usá-lo. # Positivos são relativos ao início, números negativos são relativos ao final.

js>"12345.00".slice(0,-1)
12345.0

75
Em comparação com a solução aceite, esta é a maneira mais elegante e pode ser usado mesmo com cordas criados dinamicamente
Sameer Alibhai

1
Eu gosto dessa maneira porque combina com o pensamento php para a função substr, mais fácil de lembrar e escrever em tempo real.
Pathfinder

2
@SameerAlibhai Concordo com você, mas o substringmétodo também não poderia ser usado em seqüências dinâmicas? Usando o str.length para obter dinamicamente o comprimento?
Doug Molineux

Deve-se acrescentar que o primeiro índice é inclusivo e o segundo exclusivo.
Miscreant

@KevinBeal, você pode simplesmente usar o F12 nos principais navegadores e inseri-lo no console, funciona em qualquer página e você ainda tem contexto e pode ter bibliotecas carregadas.
TWIStErRob

263

Você pode usar o método de substring dos objetos de sequência JavaScript:

s = s.substring(0, s.length - 4)

Remove incondicionalmente os últimos quatro caracteres da string s.

No entanto, se você deseja remover condicionalmente os quatro últimos caracteres, apenas se eles forem exatamente _bar :

var re = /_bar$/;
s.replace(re, "");

107
sliceé melhor aqui. s.slice(0, -4)
Tim Down

12
Alternativamente: s.slice (0, - "_ bar" .length) (útil se não se quiser codificar o número de caracteres)
Mahn

3
Eu gosto deste porque ele também ajuda a substituir um final especificado.
22813 Mike Graf Graf

162

O método mais fácil é usar o slicemétodo da string, que permite posições negativas (correspondentes a compensações do final da string):

const s = "your string";
const withoutLastFourChars = s.slice(0, -4);

Se você precisar de algo mais geral para remover tudo após (e incluindo) o último sublinhado, faça o seguinte (desde que sseja garantido que contenha pelo menos um sublinhado):

const s = "your_string";
const withoutLastChunk = s.slice(0, s.lastIndexOf("_"));
console.log(withoutLastChunk);


67

Para um número como o seu exemplo, eu recomendo fazer isso substring:

console.log(parseFloat('12345.00').toFixed(1));

Observe que, na verdade, isso arredondará o número, o que eu imagino ser desejado, mas talvez não:

console.log(parseFloat('12345.46').toFixed(1));


11
+1 É disso que o OP precisa, esqueça a falsa suposição de que há seqüências de caracteres a serem aparadas.
naugtur

2
Não é uma suposição falsa, o OP fala sobre strings. A sua é uma suposição falsa, porque o OP não fala em arredondar números.
Fernando

30

Usando a função de fatia do JavaScript:

let string = 'foo_bar';
string = string.slice(0, -4); // Slice off last four characters here
console.log(string);

Isso pode ser usado para remover '_bar' no final de uma string, de qualquer tamanho.


19

Uma expressão regular é o que você está procurando:

let str = "foo_bar";
console.log(str.replace(/_bar$/, ""));


Sua solução funciona, mas a resposta de Alex é mais abrangente. Então eu vou aceitar o dele. Obrigado!
Albert

1
Isto resolve um problema relacionado de condicional remoção, em vez de cegamente truncando
Aaron


9

E se:

let myString = "12345.00";
console.log(myString.substring(0, myString.length - 1));


9

Use regex:

let aStr = "12345.00";
aStr = aStr.replace(/.$/, '');
console.log(aStr);


Além de não reconhecer o Unicode, isso também não corresponde a quebras de linha.
user4642212 13/05

7
  1. (. *), captura qualquer caractere várias vezes

console.log("a string".match(/(.*).$/)[1]);

  1. ., corresponde ao último caractere, neste caso

console.log("a string".match(/(.*).$/));

  1. $, corresponde ao final da string

console.log("a string".match(/(.*).{2}$/)[1]);


9
Eu gosto disso porque, apesar de .splice (), você encontrou uma maneira de usar uma expressão regular.
QueueHammer

Além de não reconhecer o Unicode, isso também não corresponde a quebras de linha.
user4642212 13/05


5

Aqui está uma alternativa que eu acho que não vi nas outras respostas, apenas por diversão.

var strArr = "hello i'm a string".split("");
strArr.pop();
document.write(strArr.join(""));

Não é tão legível ou simples como fatia ou substring, mas permite que você brinque com a corda usando alguns métodos de matriz, portanto vale a pena conhecer.


4
debris = string.split("_") //explode string into array of strings indexed by "_"

debris.pop(); //pop last element off the array (which you didn't want)

result = debris.join("_"); //fuse the remainng items together like the sun

4

O caminho mais curto:

str.slice(0, -1); 

3

Se você deseja fazer arredondamentos genéricos de flutuadores, em vez de apenas aparar o último caractere:

var float1 = 12345.00,
    float2 = 12345.4567,
    float3 = 12345.982;

var MoreMath = {
    /**
     * Rounds a value to the specified number of decimals
     * @param float value The value to be rounded
     * @param int nrDecimals The number of decimals to round value to
     * @return float value rounded to nrDecimals decimals
     */
    round: function (value, nrDecimals) {
        var x = nrDecimals > 0 ? 10 * parseInt(nrDecimals, 10) : 1;
        return Math.round(value * x) / x;
    }
}

MoreMath.round(float1, 1) => 12345.0
MoreMath.round(float2, 1) => 12345.5
MoreMath.round(float3, 1) => 12346.0

EDIT: Parece que existe uma função interna para isso, como Paolo aponta. Essa solução é obviamente muito mais limpa que a minha. Use parseFloat seguido por toFixed


1
if(str.substring(str.length - 4) == "_bar")
{
    str = str.substring(0, str.length - 4);
}


1

atuação

Hoje 2020.05.13 realizo testes de soluções escolhidas no Chrome v81.0, Safari v13.1 e Firefox v76.0 no MacOs High Sierra v10.13.6.

Conclusões

  • o slice(0,-1)(D) é a solução mais rápida ou mais rápida para seqüências curtas e longas e é recomendado como solução rápida entre navegadores
  • soluções baseadas em substring(C) e substr(E) são rápidas
  • soluções baseadas em expressões regulares (A, B) são lentas / médias rápidas
  • As soluções B, F e G são lentas para seqüências longas
  • solução F é mais lenta para seqüências curtas, G é mais lenta para seqüências longas

insira a descrição da imagem aqui

Detalhes

Realizo dois testes para as soluções A , B , C , D , E ( ext ), F , G (minha)

  • para string curta de 8 caracteres (da pergunta OP) - você pode executá-lo AQUI
  • para 1M de comprimento - você pode executá-lo AQUI

As soluções são apresentadas no snippet abaixo

Aqui estão exemplos de resultados para o Chrome para cadeias curtas

insira a descrição da imagem aqui


1

Esteja ciente de que String.prototype.{ split, slice, substr, substring }opera em cadeias codificadas UTF-16

Nenhuma das respostas anteriores reconhece o Unicode. As cadeias de caracteres são codificadas como UTF-16 na maioria dos mecanismos JavaScript modernos, mas os pontos de código Unicode mais altos requerem pares substitutos ; portanto, métodos de cadeia pré-existentes mais antigos operam em unidades de código UTF-16, e não em pontos de código Unicode.

const string = "ẞ🦊";

console.log(string.slice(0, -1)); // "ẞ\ud83e"
console.log(string.substr(0, string.length - 1)); // "ẞ\ud83e"
console.log(string.substring(0, string.length - 1)); // "ẞ\ud83e"
console.log(string.replace(/.$/, "")); // "ẞ\ud83e"
console.log(string.match(/(.*).$/)[1]); // "ẞ\ud83e"

const utf16Chars = string.split("");

utf16Chars.pop();
console.log(utf16Chars.join("")); // "ẞ\ud83e"

Além disso, as respostas RegExp não correspondem a quebras de linha no final em sua forma atual:

const string = "Hello, world!\n";

console.log(string.replace(/.$/, "").endsWith("\n")); // true
console.log(string.match(/(.*).$/) === null); // true


Use o iterador de cadeia para iterar caracteres

O código compatível com Unicode utiliza o iterador da string; ver Array.frome ...espalhar . string[Symbol.iterator]também pode ser usado (por exemplo, em vez de string).

Consulte também Como dividir a cadeia Unicode em caracteres em JavaScript .

Exemplos:

const string = "ẞ🦊";

console.log(Array.from(string).slice(0, -1).join("")); // "ẞ"
console.log([
  ...string
].slice(0, -1).join("")); // "ẞ"

Use os sinalizadores seuRegExp

O sinalizador dotAllous faz .coincidir os caracteres de quebra de linha, o sinalizador unicodeouu habilita certos recursos relacionados ao Unicode.

Exemplos:

const unicodeString = "ẞ🦊",
  lineBreakString = "Hello, world!\n";

console.log(lineBreakString.replace(/.$/s, "").endsWith("\n")); // false
console.log(lineBreakString.match(/(.*).$/s) === null); // false
console.log(unicodeString.replace(/.$/su, "")); // ẞ
console.log(unicodeString.match(/(.*).$/su)[1]); // ẞ

// Now `split` can be made Unicode-aware:

const unicodeCharacterArray = unicodeString.split(/(?:)/su),
  lineBreakCharacterArray = lineBreakString.split(/(?:)/su);

unicodeCharacterArray.pop();
lineBreakCharacterArray.pop();
console.log(unicodeCharacterArray.join("")); // "ẞ"
console.log(lineBreakCharacterArray.join("").endsWith("\n")); // false


Observe que alguns grafemas consistem em mais de um ponto de código, por exemplo, 🏳️‍🌈que consiste na sequência 🏳(U + 1F3F3), VS16(U + FE0F) , ZWJ(U + 200D) , 🌈(U + 1F308). Aqui, ainda Array.fromvai dividir isso em quatro "caracteres". É possível fazer a correspondência desses itens com a propriedade Unicode .


-1

Nos casos em que você deseja remover algo próximo ao final de uma string (no caso de strings de tamanho variável), você pode combinar slice () e substr ().

Eu tinha uma string com marcação, construída dinamicamente, com uma lista de tags de âncora separadas por vírgula. A string era algo como:

var str = "<a>text 1,</a><a>text 2,</a><a>text 2.3,</a><a>text abc,</a>";

Para remover a última vírgula, fiz o seguinte:

str = str.slice(0, -5) + str.substr(-4);

-3

Tente o seguinte:

<script>
    var x="foo_foo_foo_bar";
    for (var i=0; i<=x.length; i++) {
        if (x[i]=="_" && x[i+1]=="b") {
            break;
        }
        else {
            document.write(x[i]);
        }
    }
</script>

Você também pode tentar o exemplo de trabalho ao vivo em http://jsfiddle.net/informativejavascript/F7WTn/87/ .


3
Obrigado Kamal. No entanto, marquei a resposta acima como aceita para minhas necessidades. Observe a marca de seleção verde acima. No entanto, verifiquei seu código. :) Agora, na minha situação, só conheço a sequência comum de caracteres finais. Seria melhor começar a verificar a partir do final da string. Sua sugestão falharia se eu tivesse uma string parecida com "foo_b_bar" e só queira remover o último "_bar". Obrigado embora! É uma experiência bastante interessante fazer uma pergunta há mais de 2 anos e ainda receber respostas para ela hoje. :)
Albert

-4

@Jason S:

Você pode usar fatia! Você só precisa ter certeza de que sabe usá-lo. # Positivos são relativos ao início, números negativos são relativos ao final.

js> "12345.00" .slice (0, -1) 12345.0

Desculpe pela minha graphomany, mas a postagem foi marcada como 'jquery' anteriormente. Portanto, você não pode usar slice () dentro do jQuery porque o slice () é o método jQuery para operações com elementos DOM, não substrings ... Em outras palavras, responda @ Jon Erickson sugerir uma solução realmente perfeita.

No entanto, seu método funciona com a função jQuery, dentro de Javascript simples. É preciso dizer que, devido à última discussão nos comentários, que o jQuery é uma extensão muito mais renovável do JS do que o ECMAScript mais conhecido de seus pais.

Aqui também existem dois métodos:

como nosso:

string.substring(from,to) como mais se o índice 'to' nulled retorna o restante da string. então: string.substring(from) positivo ou negativo ...

e alguns outros - substr () - que fornecem faixa de substring e 'length' podem ser positivos apenas: string.substr(start,length)

Alguns mantenedores também sugerem que o último método string.substr(start,length)não funciona ou funciona com erro para o MSIE.


3
O que você quer dizer? String.prototype.sliceé um método nativo
naugtur 5/12/12

apenas o que você disse. Método nativo Javascript, mas também slice()método jQuery para manipulação DOM: API jQuery: .slice () . E CERTO, isso PODE SER FIGURADO como uma herança polimórfica de JS Array.slice (), mas são dois métodos diferentes, e acho que precisamos diferenciá-lo. Portanto, é apenas uma aproximação a esse conhecimento.
rápida

12
Se você chamar .sliceuma variável que é uma string, ela fará exatamente o que o OP queria. Não importa se ele está "dentro do jQuery" e não há como "interferir" de maneira alguma, a menos que você o substitua String.prototypepelo jQuery, o que, com certeza, impedirá o funcionamento de QUALQUER código javascript. Sua resposta apenas diz que outra resposta não é boa e o argumento que você fornece está incorreto.
naugtur

1
Posso concordar com @naugtur que esta resposta está errada, o método de fatia da string não é efetuado pelo jQuery.
reconbota

1
Eu acho que o argumento que naugtur estava dizendo era justamente que, viável, você pode acabar com uma string envolvida por um objeto jQuery (por exemplo, se você fizer alguma .datamanipulação sofisticada e acabar com essa "string"), que, se você a chamar slice, não faria o que você quer. Dito isto, esta não é realmente uma resposta útil.
MAAdhaTTah

-8

Use substring para obter tudo à esquerda de _bar. Mas primeiro você precisa obter o instr de _bar na string:

str.substring(3, 7);

3 é esse começo e 7 é o comprimento.


1
isso funciona apenas em "foo_bar" e não em "foo_foo_bar", a questão era sobre uma string com qualquer comprimento, mas com um fim conhecido.
Design by Adrian
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.