JavaScript cortar / cortar / recortar el último carácter de la cadena

1975

Tengo una cadena, 12345.00y me gustaría que volviera 12345.0.

Lo he mirado trim, pero parece que solo está recortando espacios en blanco y sliceque no veo cómo funcionaría esto. ¿Alguna sugerencia?

Phill Pafford
fuente
36
¿Te importa redondear? 12345.46 = 12345.5 o 12345.4?
RSolberg
99
¿Sabes cuál es el sufijo o quieres dividir y eliminar la última palabra según tus guiones bajos?
Cᴏʀʏ
65
Ho ho ho, @RSolberg: ¡no puedes redondear una cuerda!
Ziggy
50
@Ziggy dice qué? Math.round('0.5') === 1;)
TWiStErRob
16
@TWiStErRob Oh JavaScript, ¿qué voy a hacer contigo? * sacude la cabeza *
Chuck Le Butt

Respuestas:

3216

Puedes usar la subcadena función de :

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

Esta es la respuesta aceptada, pero según las conversaciones a continuación, la sintaxis de corte es mucho más clara:

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

Jon Erickson
fuente
23
@Kheu: la notación de corte es mucho más limpia para mí. Anteriormente estaba usando la versión de subcadena. ¡Gracias!
Matt Ball el
32
perdóname si me equivoco, pero ¿no necesitas asignar el valor de str.substring a str nuevamente? Me gustastr = str.substring(0, str.length -1);
Doug Molineux
10
Los métodos slice& substringson casi todos iguales; excepto que slice()acepta un índice negativo, relativo al final de la cadena, pero no el substring, arroja un out-of-bounderror
Amol M Kulkarni
20
En caso de que alguien se lo pregunte, substringes un 11% más rápido que slice. jsperf.com/js-slice-vs-substring-test
BenR
19
la subcadena son micro optimizaciones increíbles que no creo que debas hacer. Maximice primero la legibilidad. Luego, optimice la fruta baja si es necesario.
Alfred
1307

¡Puedes usar rebanada ! Solo tiene que asegurarse de saber cómo usarlo. Los números positivos son relativos al principio, los números negativos son relativos al final.

js>"12345.00".slice(0,-1)
12345.0
Jason S
fuente
75
En comparación con la solución aceptada, esto es mucho más elegante y se puede usar incluso con cadenas creadas dinámicamente
Sameer Alibhai
1
Me gusta de esta manera porque combina con el pensamiento php para la función substr, más fácil de recordar y escribir sobre la marcha.
Pathfinder
2
@SameerAlibhai Estoy de acuerdo con usted, pero ¿no podría substringusarse el método también en cadenas dinámicas? ¿Usando str.length para obtener dinámicamente la longitud?
Doug Molineux
Debe agregarse que el primer índice es inclusivo y el segundo exclusivo.
Malhechor
@KevinBeal puede usar F12 en los navegadores principales e ingresarlo en la consola, funciona en cualquier página e incluso tiene contexto y puede cargar bibliotecas.
TWiStErRob
263

Puede usar el método de subcadena de los objetos de cadena de JavaScript:

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

Elimina incondicionalmente los últimos cuatro caracteres de la cadena s.

Sin embargo, si desea eliminar condicionalmente los últimos cuatro caracteres, solo si son exactamente _bar :

var re = /_bar$/;
s.replace(re, "");
Alex Martelli
fuente
107
sliceEs mejor aquí. s.slice(0, -4)
Tim Down
12
Alternativamente: s.slice (0, - "_ bar" .length) (útil si uno no quiere codificar el número de caracteres)
Mahn
3
Me gusta este porque también da ayuda para reemplazar un final específico.
Mike Graf
162

El método más fácil es usar el slicemétodo de la cadena, que permite posiciones negativas (correspondientes a las compensaciones desde el final de la cadena):

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

Si necesita algo más general para eliminar todo después (e incluir) el último guión bajo, puede hacer lo siguiente (siempre que sse garantice que contenga al menos un guión bajo):

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

Tim Down
fuente
67

Para un número como su ejemplo, recomendaría hacer esto de nuevo substring:

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

Sin embargo, tenga en cuenta que esto realmente redondeará el número, lo que me imagino que es deseado, pero tal vez no:

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

Paolo Bergantino
fuente
11
+1 Esto es lo que necesita OP, olvide la suposición falsa de que hay cadenas que se deben recortar.
naugtur
2
No es una suposición falsa, OP habla de cadenas. La suya es una suposición falsa porque OP no habla de redondear números.
Fernando
30

Usando la función de división de JavaScript:

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

Esto podría usarse para eliminar '_bar' al final de una cadena, de cualquier longitud.

Akshay Joshi
fuente
19

Una expresión regular es lo que estás buscando:

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

w35l3y
fuente
Su solución funciona, pero la respuesta de Alex es más completa. Entonces aceptaré el suyo. ¡Gracias!
Albert
1
Esto resuelve un problema relacionado de eliminación condicional en lugar de truncamiento ciego
Aaron
10

Prueba esto:

const myString = "Hello World!";
console.log(myString.slice(0, -1));

Somwang Souksavatd
fuente
9

Qué tal si:

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

dariom
fuente
9

Utilice expresiones regulares:

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

Marc477
fuente
Además de no ser consciente de Unicode, esto tampoco coincide con los saltos de línea.
user4642212
7
  1. (. *), captura cualquier personaje varias veces

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

  1. ., coincide con el último carácter, en este caso

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

  1. $, coincide con el final de la cadena

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

sitios
fuente
99
Me gusta esto porque a pesar de .splice () encontraste una manera de usar una expresión regular.
QueueHammer
Además de no ser consciente de Unicode, esto tampoco coincide con los saltos de línea.
user4642212
6

const str = "test!";
console.log(str.slice(0, -1));

dota2pro
fuente
3
¿Qué agrega esto, en comparación con todas las otras respuestas?
Dan Dascalescu
5

Aquí hay una alternativa que no creo haber visto en las otras respuestas, solo por diversión.

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

No es tan legible o simple como el corte o la subcadena, pero le permite jugar con la cadena usando algunos buenos métodos de matriz, por lo que vale la pena saberlo.

Mark Walters
fuente
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
uofc
fuente
4

El camino más corto:

str.slice(0, -1); 
Idan
fuente
3

Si desea hacer un redondeo genérico de carrozas, en lugar de simplemente recortar el último carácter:

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

EDITAR: Parece que existe una función integrada para esto, como señala Paolo. Esa solución es obviamente mucho más limpia que la mía. Use parseFloat seguido de toFixed

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

Actuación

Hoy 2020.05.13 realizo pruebas de las soluciones elegidas en Chrome v81.0, Safari v13.1 y Firefox v76.0 en MacOs High Sierra v10.13.6.

Conclusiones

  • el slice(0,-1)(D) es rápida o solución más rápida para cadenas cortas y largas y se recomienda como solución multi-navegador rápido
  • Las soluciones basadas en substring(C) y substr(E) son rápidas
  • Las soluciones basadas en expresiones regulares (A, B) son lentas / medio rápidas
  • las soluciones B, F y G son lentas para cadenas largas
  • la solución F es más lenta para cadenas cortas, G es más lenta para cadenas largas

ingrese la descripción de la imagen aquí

Detalles

Realizo dos pruebas para las soluciones A , B , C , D , E ( ext ), F , G (my)

  • para cadena corta de 8 caracteres (de la pregunta OP): puede ejecutarlo AQUÍ
  • para una cadena larga de 1M: puede ejecutarla AQUÍ

Las soluciones se presentan en el siguiente fragmento

Aquí hay resultados de ejemplo para Chrome para cadena corta

ingrese la descripción de la imagen aquí

Kamil Kiełczewski
fuente
1

Tenga en cuenta que String.prototype.{ split, slice, substr, substring }funciona con cadenas codificadas UTF-16

Ninguna de las respuestas anteriores es compatible con Unicode. Las cadenas están codificadas como UTF-16 en la mayoría de los motores JavaScript modernos, pero los puntos de código Unicode más altos requieren pares sustitutos , por lo que los métodos de cadena más antiguos y existentes operan en unidades de código UTF-16, no en puntos 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"

Además, las respuestas de RegExp no coinciden con los saltos de línea al final en su forma actual:

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

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


Use el iterador de cadena para iterar caracteres

El código compatible con Unicode utiliza el iterador de la cadena; Ver Array.fromy ...difundir . string[Symbol.iterator]se puede usar (por ejemplo, en lugar destring ) también.

Consulte también Cómo dividir cadenas Unicode en caracteres en JavaScript .

Ejemplos:

const string = "ẞ🦊";

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

Use las banderas sy uen unRegExp

El indicador dotAllos hace .coincidir los caracteres de salto de línea, el indicador unicodeou habilita ciertas funciones relacionadas con Unicode.

Ejemplos:

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


Tenga en cuenta que algunos grafemas consisten en más de un punto de código, por ejemplo, 🏳️‍🌈que consiste en la secuencia 🏳(U + 1F3F3), VS16(U + FE0F) , ZWJ(U + 200D) , 🌈(U + 1F308). Aquí, incluso Array.fromdividirá esto en cuatro "personajes". Es posible que coincidan con la propuesta de propiedades de secuencia de la propiedad Unicode .

usuario4642212
fuente
-1

En los casos en que desee eliminar algo que esté cerca del final de una cadena (en el caso de cadenas de tamaño variable), puede combinar slice () y substr ().

Tenía una cadena con marcado, construida dinámicamente, con una lista de etiquetas de anclaje separadas por comas. La cadena era algo así como:

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

Para eliminar la última coma, hice lo siguiente:

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

Prueba esto:

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

También puede probar el ejemplo de trabajo en vivo en http://jsfiddle.net/informativejavascript/F7WTn/87/ .

kamal
fuente
3
Gracias kamal Sin embargo, he marcado la respuesta anterior como aceptada para mis necesidades. Observe la marca de verificación verde arriba. Sin embargo, revisé tu código. :) Ahora, en mi situación, solo conozco la secuencia común de caracteres finales. Sería mejor comenzar a verificar desde el final de la cadena. Su sugerencia fallaría si tengo una cadena que se parece a "foo_b_bar", y solo quiero eliminar la última "_bar". Gracias sin embargo! Hacer una pregunta hace más de 2 años es una experiencia bastante interesante y aún hoy recibo respuestas. :)
Albert
-4

@Jason S:

¡Puedes usar rebanada! Solo tiene que asegurarse de saber cómo usarlo. Los números positivos son relativos al principio, los números negativos son relativos al final.

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

Lo siento por mi grafomanía, pero la publicación fue etiquetada 'jquery' anteriormente. Por lo tanto, no puede usar slice () dentro de jQuery porque slice () es un método jQuery para operaciones con elementos DOM, no subcadenas ... En otras palabras, la respuesta @Jon Erickson sugiere una solución realmente perfecta.

Sin embargo, su método funcionará con la función jQuery, dentro de Javascript simple. Es necesario decir, debido a la última discusión en los comentarios, que jQuery es una extensión de JS con mucha más frecuencia renovable que su ECMAScript más conocido.

Aquí también existen dos métodos:

como el nuestro:

string.substring(from,to) como plus si 'to' index nulled devuelve el resto de la cadena. entonces: string.substring(from) positivo o negativo ...

y algunos otros - substr () - que proporcionan un rango de subcadena y 'longitud' solo pueden ser positivos: string.substr(start,length)

También algunos mantenedores sugieren que el último método string.substr(start,length)no funciona o funciona con error para MSIE.

rápido
fuente
3
¿Qué quieres decir? String.prototype.slicees un método nativo
naugtur
es solo lo que dijiste. Método nativo Javascript, pero también slice()método jQuery para la manipulación DOM: jQuery API: .slice () . Y SEGURO, eso PUEDE FIGURARSE como una herencia polimórfica de JS Array.slice (), pero es dos métodos diferentes, y creo que necesita distinguirlo. Entonces es solo una aproximación a este conocimiento.
rápido
12
Si llama .slicea una variable que es una cadena, hará exactamente lo que el OP quería. No importa si está "dentro de jQuery" y no hay forma de que pueda "interferir" de ninguna manera a menos que sobrescriba String.prototypecon jQuery, lo que estoy seguro evitará que CUALQUIER código de JavaScript funcione. Su respuesta solo dice que otra respuesta no es buena y el argumento que proporciona es incorrecto.
naugtur
1
Estoy de acuerdo con @naugtur, esta respuesta es incorrecta, jQuery no afecta el método de división de la cadena.
Reconbot
1
Creo que el punto que Naugtur estaba haciendo era solo que, de manera factible, podrías terminar con una cadena envuelta por un objeto jQuery (por ejemplo, si haces alguna .datamanipulación sofisticada y terminas con esta "cadena"), que si la invocaste slice, No haría lo que quisieras. Dicho esto, esta no es realmente una respuesta útil.
mAAdhaTTah
-8

Use la subcadena para obtener todo a la izquierda de _bar. Pero primero tienes que obtener el instr de _bar en la cadena:

str.substring(3, 7);

3 es ese comienzo y 7 es la longitud.

quejas
fuente
1
esto solo funciona en "foo_bar", no en "foo_foo_bar", la pregunta era sobre una cadena con cualquier longitud pero con un final conocido.
Diseño de Adrian