DEV Community

byby
byby

Posted on • Originally published at byby.dev

How to remove last character from string in JavaScript

There are many scenarios where you may need to remove the last character from a string. For example, you may want to:

  • Remove a trailing slash or comma from a URL or a list
  • Remove a newline or carriage return character from a text file
  • Remove a punctuation mark from a sentence or a word
  • Remove a digit or a letter from a number or a code

In JavaScript, common approachs are to use the substring() or slice(), which allow you to extract a portion of a string based on the starting and ending indices. By specifying a range that excludes the last character, you effectively remove it from the string.

Using slice method

The slice() method of String is used to extract a part of a string and return it as a new string, without modifying the original string. You can specify the start and end indexes of the extracted part, or use negative indexes to count from the end of the string.

let str = "Hello world!";
str = str.slice(0, -1);
console.log(str); // "Hello world"
Enter fullscreen mode Exit fullscreen mode

Here slice(0, -1) removes the last character because -1 means the last index of the string. You can also use str.length - 1 instead of -1 to get the same result.

Using substring method

The substring() method of String is used to return a part of the string from a start index to an end index, excluding the end index. It does not change the original string, but returns a new string.

let str = "Hello world!";
str = str.substring(0, str.length - 1);
console.log(str); // "Hello world"
Enter fullscreen mode Exit fullscreen mode

The substring(0, str.length - 1) method removes the last character because str.length - 1 is the last index of the string. You cannot use negative indexes with substring().

Using replace method

The replace() method returns a new string with one, some, or all matches of a pattern replaced by a replacement. The pattern can be a string or regular expression, and the replacement can be a string or a function called for each match.

let str = "Hello World!";
str = str.replace(/.$/, "");
console.log(str); // "Hello World"
Enter fullscreen mode Exit fullscreen mode

The . within the regular expression represents any character, and the $ denotes the end of the string. So, .$ matches the last character in the string. By replacing it with an empty string, that character is removed.

Please note that if the string contains newline characters or multiple Unicode code points, the regular expression approach may not behave as expected. In such cases, using substring() or slice() methods might be more suitable.

Top comments (10)

Collapse
 
lionelrowe profile image
lionel-rowe • Edited

Do they pass the Pile of Poo Test though?

const str = 'Hello WorldπŸ’©'
// slice
str.slice(0, -1) // 'Hello World\uD83D'
// substring
str.substring(0, str.length - 1) // 'Hello World\uD83D'
// replace
str.replace(/.$/, '') // 'Hello World\uD83D'
Enter fullscreen mode Exit fullscreen mode

You can fix the replace version by adding a u or v flag to the regex:

str.replace(/.$/u, '') // 'Hello World'
Enter fullscreen mode Exit fullscreen mode

Or, depending what you mean by "char", you could get more robust behavior for grapheme clusters using Intl.Segmenter:

function removeLastUnicodeChar(str) {
    return str.replace(/.$/u, '')
}

function removeLastGrapheme(str) {
    let index = 0
    for (const s of new Intl.Segmenter('en-US', { granularity: 'grapheme' }).segment(str)) {
        index = s.index
    }
    return str.slice(0, index)
}

const str = 'ΰΈ›ΰΈ£ΰΈ°ΰΉ€ΰΈžΰΈ“ΰΈ΅'
removeLastUnicodeChar(str) // 'ΰΈ›ΰΈ£ΰΈ°ΰΉ€ΰΈžΰΈ“'
removeLastGrapheme(str)    // 'ΰΈ›ΰΈ£ΰΈ°ΰΉ€ΰΈž'
Enter fullscreen mode Exit fullscreen mode
Collapse
 
jonrandy profile image
Jon Randy πŸŽ–οΈ

Mine works with poo! πŸ’©

Collapse
 
schmoris profile image
Boris

Great point!

Collapse
 
jonrandy profile image
Jon Randy πŸŽ–οΈ • Edited
const removeLast=(str, [a,...b]=[...str].reverse()) => b.reverse().join``

console.log(removeLast('hello'))
Enter fullscreen mode Exit fullscreen mode

πŸ˜›

Collapse
 
bybydev profile image
byby

Nice. Your code achieves its purpose in a single line using clever techniques like destructuring and spread operator.

Collapse
 
0x8c profile image
tiff

While one liners are cool, the readability is poor and if you were working with a team, hard to maintain. Looks pretty though.

Collapse
 
jonrandy profile image
Jon Randy πŸŽ–οΈ • Edited

I wasn't suggesting using it in production code - it's just another method (and an inefficient one at that, although it does pass the 'Pile of poo' test).

Readability is subjective πŸ‘

Collapse
 
steeve profile image
Steeve

a bit over-engineered ahah

Collapse
 
efpage profile image
Eckehard

But, which one is fastest?

Collapse
 
efpage profile image
Eckehard

OK, here is the answer:

"Hello World": 1 Mio operations in a for(;;)-loop

slice = 25ms
substr = 11ms
replace = 168ms

"Lorem ipsum dolor sit amet ... dolor sit amet." (591 charakters): 1 Mio operations in a for(;;)-loop

slice = 29ms
substr = 36ms
replace = 122ms

As always, results are surprising...

See code here