2200

I have a string, 12345.00, and I would like it to return 12345.0.

I have looked at trim, but it looks like it is only trimming whitespace and slice which I don't see how this would work. Any suggestions?

Kamil Kiełczewski
  • 53,729
  • 20
  • 259
  • 241
Phill Pafford
  • 77,927
  • 86
  • 256
  • 378

26 Answers26

3521

You can use the substring function:

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

This is the accepted answer, but as per the conversations below, the slice syntax is much clearer:

let str = "12345.00";
str = str.slice(0, -1); 
console.log(str);
dota2pro
  • 5,432
  • 5
  • 25
  • 52
Jon Erickson
  • 102,662
  • 42
  • 131
  • 170
  • 26
    @Kheu - the slice notation is much cleaner to me. I was previously using the substring version. Thanks! – Matt Ball Apr 13 '10 at 14:09
  • 35
    forgive me if I'm wrong but don't you need to assign the value of str.substring to str again? Like `str = str.substring(0, str.length -1);` – Doug Molineux Jul 15 '11 at 16:10
  • 11
    The `slice` & `substring` methods are all most the same; except the that the `slice()` accepts a negative index, relative to the end of the string, but not the `substring`, it throws `out-of-bound` error – Amol M Kulkarni Apr 09 '13 at 09:45
  • 21
    In case anybody is wondering, `substring` is 11% faster than `slice`. http://jsperf.com/js-slice-vs-substring-test – BenR Apr 16 '14 at 15:53
  • 21
    substring is insane micro-optimizations which I don't think you should do. Maximize for readability first. Then optimize low hanging fruit if needed. – Alfred Jul 09 '14 at 11:10
  • 5
    @BenR not anymore, in my Chrome 46, slice is now 0.24% faster! – rorypicko Nov 30 '15 at 12:37
  • substr is the fasted method for this in most browsers. https://jsperf.com/slice-vs-substr-vs-substring-methods-long-string/2 – user2687646 Jan 21 '16 at 21:12
  • Does not work, i get `logik.js:156 Uncaught TypeError: str.slice is not a function` – Black May 04 '16 at 12:18
  • 3
    @EdwardBlack Because your str is not a string. – Izzy Aug 05 '16 at 09:18
  • 3
    slife is lice... or something like that – Bernardo Dal Corno Feb 08 '19 at 20:15
1394

You can use slice! You just have to make sure you know how to use it. Positive #s are relative to the beginning, negative numbers are relative to the end.

js>"12345.00".slice(0,-1)
12345.0
Jason S
  • 171,795
  • 155
  • 551
  • 900
  • 77
    Compared to the accepted solution, this is way more elegant and can be used even with dynamically created strings – Sameer Alibhai Jul 03 '12 at 20:41
  • 1
    I like this way because it jives with php thinking for substr function, easier to remember and write on the fly. – pathfinder Mar 15 '13 at 06:24
  • 2
    @SameerAlibhai I agree with you, but couldn't the `substring` method be used on dynamic strings too? By using the str.length to dynamically get the length? – Doug Molineux Sep 02 '14 at 22:41
  • Should be added that the first index is inclusive and the second exclusive. – Miscreant Jul 07 '15 at 16:27
  • @KevinBeal you can just use F12 in mainstream browsers and enter it in the Console, works on any page and you even have context and can have libraries loaded. – TWiStErRob Jul 18 '15 at 12:43
  • None of the other answers are even worth looking at. – dgo Sep 16 '15 at 20:50
  • 1
    This works for removing the last character, but beware if you want to remove a variable number of characters; `.slice(0, -0)` will return an empty string! – Nigel Nelson Apr 23 '19 at 01:18
  • This should be the accepted answer. – loop Jan 17 '21 at 17:58
270

You can use the substring method of JavaScript string objects:

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

It unconditionally removes the last four characters from string s.

However, if you want to conditionally remove the last four characters, only if they are exactly _bar:

var re = /_bar$/;
s.replace(re, "");
Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Alex Martelli
  • 762,786
  • 156
  • 1,160
  • 1,345
168

The easiest method is to use the slice method of the string, which allows negative positions (corresponding to offsets from the end of the string):

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

If you needed something more general to remove everything after (and including) the last underscore, you could do the following (so long as s is guaranteed to contain at least one underscore):

const s = "your_string";
const withoutLastChunk = s.slice(0, s.lastIndexOf("_"));
console.log(withoutLastChunk);
dota2pro
  • 5,432
  • 5
  • 25
  • 52
Tim Down
  • 292,637
  • 67
  • 429
  • 506
70

For a number like your example, I would recommend doing this over substring:

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

Do note that this will actually round the number, though, which I would imagine is desired but maybe not:

console.log(parseFloat('12345.46').toFixed(1));
dota2pro
  • 5,432
  • 5
  • 25
  • 52
Paolo Bergantino
  • 449,396
  • 76
  • 509
  • 431
  • 11
    +1 This is what OP needs, forget the false assumption that there are strings to be trimmed. – naugtur Dec 05 '12 at 17:23
  • 4
    It is not a false assumption, OP talks about strings. Yours is a false assumption because OP doesn't talk about rounding numbers. – Fernando Jun 02 '15 at 11:52
31

Using JavaScript's slice function:

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

This could be used to remove '_bar' at end of a string, of any length.

dota2pro
  • 5,432
  • 5
  • 25
  • 52
Akshay Joshi
  • 465
  • 7
  • 10
21

A regular expression is what you are looking for:

let str = "foo_bar";
console.log(str.replace(/_bar$/, ""));
dota2pro
  • 5,432
  • 5
  • 25
  • 52
w35l3y
  • 7,389
  • 2
  • 35
  • 49
11

Try this:

const myString = "Hello World!";
console.log(myString.slice(0, -1));
dota2pro
  • 5,432
  • 5
  • 25
  • 52
Somwang Souksavatd
  • 3,974
  • 26
  • 28
10

Use regex:

let aStr = "12345.00";
aStr = aStr.replace(/.$/, '');
console.log(aStr);
dota2pro
  • 5,432
  • 5
  • 25
  • 52
Marc477
  • 133
  • 1
  • 7
10

Be aware that String.prototype.{ split, slice, substr, substring } operate on UTF-16 encoded strings

None of the previous answers are Unicode-aware. Strings are encoded as UTF-16 in most modern JavaScript engines, but higher Unicode code points require surrogate pairs, so older, pre-existing string methods operate on UTF-16 code units, not Unicode code points.

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"

In addition, RegExp methods, as suggested in older answers, don’t match line breaks at the end:

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

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

Use the string iterator to iterate characters

Unicode-aware code utilizes the string’s iterator; see Array.from and ... spread. string[Symbol.iterator] can be used (e.g. instead of string) as well.

Also see How to split Unicode string to characters in JavaScript.

Examples:

const string = "ẞ";

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

Use the s and u flags on a RegExp

The dotAll or s flag makes . match line break characters, the unicode or u flag enables certain Unicode-related features. Note that, when using the u flag, you eliminate unnecessary identity escapes, as these are invalid in a u regex, e.g. \[ is fine, as it would start a character class without the backslash, but \: isn’t, as it’s a : with or without the backslash, so you need to remove the backslash.

Examples:

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

Note that some graphemes consist of more than one code point, e.g. ️‍ which consists of the sequence (U+1F3F3), VS16 (U+FE0F), ZWJ (U+200D), (U+1F308). Here, even Array.from will split this into four “characters”. Matching those is possible with the Unicode property escapes sequence properties proposal.

Sebastian Simon
  • 14,320
  • 6
  • 42
  • 61
9

How about:

let myString = "12345.00";
console.log(myString.substring(0, myString.length - 1));
dota2pro
  • 5,432
  • 5
  • 25
  • 52
dariom
  • 4,245
  • 26
  • 40
7
  1. (.*), captures any character multiple times

console.log("a string".match(/(.*).$/)[1]);
  1. ., matches last character, in this case

console.log("a string".match(/(.*).$/));
  1. $, matches the end of the string

console.log("a string".match(/(.*).{2}$/)[1]);
dota2pro
  • 5,432
  • 5
  • 25
  • 52
sites
  • 19,991
  • 16
  • 81
  • 136
6

const str = "test!";
console.log(str.slice(0, -1));
dota2pro
  • 5,432
  • 5
  • 25
  • 52
6

The shortest way:

str.slice(0, -1); 
Idan
  • 1,696
  • 15
  • 26
5

Here is an alternative that i don't think i've seen in the other answers, just for fun.

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

Not as legible or simple as slice or substring but does allow you to play with the string using some nice array methods, so worth knowing.

Mark Walters
  • 10,729
  • 6
  • 31
  • 47
5

Performance

Today 2020.05.13 I perform tests of chosen solutions on Chrome v81.0, Safari v13.1 and Firefox v76.0 on MacOs High Sierra v10.13.6.

Conclusions

  • the slice(0,-1)(D) is fast or fastest solution for short and long strings and it is recommended as fast cross-browser solution
  • solutions based on substring (C) and substr(E) are fast
  • solutions based on regular expressions (A,B) are slow/medium fast
  • solutions B, F and G are slow for long strings
  • solution F is slowest for short strings, G is slowest for long strings

enter image description here

Details

I perform two tests for solutions A, B, C, D, E(ext), F, G(my)

  • for 8-char short string (from OP question) - you can run it HERE
  • for 1M long string - you can run it HERE

Solutions are presented in below snippet

function A(str) {
  return str.replace(/.$/, '');
}

function B(str) {
  return str.match(/(.*).$/)[1];
}

function C(str) {
  return str.substring(0, str.length - 1);
}

function D(str) {
  return str.slice(0, -1); 
}

function E(str) {
  return str.substr(0, str.length - 1);
}

function F(str) {
  let s= str.split("");
  s.pop();
  return s.join("");
}

function G(str) {
  let s='';
  for(let i=0; i<str.length-1; i++) s+=str[i];
  return s;
 }



// ---------
// TEST
// ---------

let log = (f)=>console.log(`${f.name}: ${f("12345.00")}`);

[A,B,C,D,E,F,G].map(f=>log(f));
This snippet only presents soutions

Here are example results for Chrome for short string

enter image description here

Community
  • 1
  • 1
Kamil Kiełczewski
  • 53,729
  • 20
  • 259
  • 241
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
  • 490
  • 5
  • 13
3

If you want to do generic rounding of floats, instead of just trimming the last character:

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: Seems like there exists a built in function for this, as Paolo points out. That solution is obviously much cleaner than mine. Use parseFloat followed by toFixed

PatrikAkerstrand
  • 43,625
  • 11
  • 74
  • 92
2

https://stackoverflow.com/questions/34817546/javascript-how-to-delete-last-two-characters-in-a-string

Just use trim if you don't want spaces

"11.01 °C".slice(0,-2).trim()

profile_-1
  • 37
  • 3
1
if(str.substring(str.length - 4) == "_bar")
{
    str = str.substring(0, str.length - 4);
}
Matthew Flaschen
  • 255,933
  • 45
  • 489
  • 528
0

You can, in fact, remove the last arr.length - 2 items of an array using arr.length = 2, which if the array length was 5, would remove the last 3 items.

Sadly, this does not work for strings, but we can use split() to split the string, and then join() to join the string after we've made any modifications.

var str = 'string'

String.prototype.removeLast = function(n) {
  var string = this.split('')
  string.length = string.length - n

  return string.join('')
}

console.log(str.removeLast(3))
GalaxyCat105
  • 2,105
  • 4
  • 12
  • 26
0

Via slice(indexStart, indexEnd) method - note, this does NOT CHANGE the existing string, it creates a copy and changes the copy.

console.clear();
let str = "12345.00";
let a = str.slice(0, str.length -1)
console.log(a, "<= a");
console.log(str, "<= str is NOT changed");

Via Regular Expression method - note, this does NOT CHANGE the existing string, it creates a copy and changes the copy.

console.clear();
let regExp = /.$/g
let b = str.replace(regExp,"")
console.log(b, "<= b");
console.log(str, "<= str is NOT changed");

Via array.splice() method -> this only works on arrays, and it CHANGES, the existing array (so careful with this one), you'll need to convert a string to an array first, then back.

console.clear();
let str = "12345.00";
let strToArray = str.split("")
console.log(strToArray, "<= strToArray");
let spliceMethod = strToArray.splice(str.length-1, 1)
str = strToArray.join("")
console.log(str, "<= str is changed now");
-1

In cases where you want to remove something that is close to the end of a string (in case of variable sized strings) you can combine slice() and substr().

I had a string with markup, dynamically built, with a list of anchor tags separated by comma. The string was something like:

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

To remove the last comma I did the following:

str = str.slice(0, -5) + str.substr(-4);
Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
-3

Try this:

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

You can also try the live working example on http://jsfiddle.net/informativejavascript/F7WTn/87/.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
kamal
  • 139
  • 6
  • 3
    Thanks kamal. However, I've marked the answer above as accepted for my needs. Notice the green check mark above. Though, I did check your code. :) Now, in my situation, I only know the common end character sequence. It would be better to just start checking from the end of the string. Your suggestion would fail if I have a string that looks like "foo_b_bar", and I only want to take out the last "_bar". Thanks though! It's quite an interesting experience to ask a question over 2 years ago, and still receive answers for it today. :) – Albert Dec 28 '12 at 07:09
-4

@Jason S:

You can use slice! You just have to make sure you know how to use it. Positive #s are relative to the beginning, negative numbers are relative to the end.

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

Sorry for my graphomany but post was tagged 'jquery' earlier. So, you can't use slice() inside jQuery because slice() is jQuery method for operations with DOM elements, not substrings ... In other words answer @Jon Erickson suggest really perfect solution.

However, your method will works out of jQuery function, inside simple Javascript. Need to say due to last discussion in comments, that jQuery is very much more often renewable extension of JS than his own parent most known ECMAScript.

Here also exist two methods:

as our:

string.substring(from,to) as plus if 'to' index nulled returns the rest of string. so: string.substring(from) positive or negative ...

and some other - substr() - which provide range of substring and 'length' can be positive only: string.substr(start,length)

Also some maintainers suggest that last method string.substr(start,length) do not works or work with error for MSIE.

swift
  • 270
  • 2
  • 5
  • 3
    What do you mean? `String.prototype.slice` is a native method – naugtur Dec 05 '12 at 10:38
  • it only what you said. Javascript native method, but also jQuery `slice()` method for DOM manipulation: [**jQuery API: .slice()**](http://api.jquery.com/slice/). AND SURE, that is CAN BE FIGURED like a polymorphic inheritance of JS Array.slice(), but it is two different methods, and I think needs to tell it apart. So it's just an approximation to this knowledge. – swift Dec 05 '12 at 10:58
  • why not? ... my answer so really not useful? ... `slice` is generic method for BOTH prototypes `Array` and `String` ... look: [Array: Array generic methods](https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array#Array_generic_methods) and compare with [String: String generic methods](https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String#String_generic_methods) ... but it so very relative NATIVITY for ... and over that a `slice` interferes to jQuery :) question btw tagged `jquery` – swift Dec 05 '12 at 16:00
  • 12
    If you call `.slice` on a variable that is a string, it's going to do just what the OP wanted. It doesn't matter if it's "inside jQuery" and there is no way it could "interfere" in any way unless you overwrite `String.prototype` with jQuery, which I am sure will prevent ANY javascript code from working. Your answer just says that other answer is not good and the argument you provide is incorrect. – naugtur Dec 05 '12 at 17:18
  • and you decided discuss it with me? then you should to know that your mythology is many more inconsistent. yes. just it. – swift Dec 05 '12 at 18:02
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/20649/discussion-between-naugtur-and-swift) – naugtur Dec 05 '12 at 18:28
  • 1
    I can agree with @naugtur this answer is wrong, the string's slice method is not effected by jQuery. – reconbot Jun 11 '13 at 02:58
  • 1
    I think the point naugtur was making was just that, feasibly, you could end up with a string wrapped by a jQuery object (e.g. if you do some fancy `.data` manipulation and end up with this "string"), which if you called `slice` on it, would not do what you want. That said, this isn't really a helpful answer. – mAAdhaTTah Apr 25 '16 at 18:09
-8

Use substring to get everything to the left of _bar. But first you have to get the instr of _bar in the string:

str.substring(3, 7);

3 is that start and 7 is the length.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
griegs
  • 22,002
  • 28
  • 113
  • 201