Ruby, Remove Last N Characters from a String

Ruby, remove last N characters from a string?


Ruby 2.5+

As of Ruby 2.5 you can use delete_suffix or delete_suffix! to achieve this in a fast and readable manner.

The docs on the methods are here.

If you know what the suffix is, this is idiomatic (and I'd argue, even more readable than other answers here):

'abc123'.delete_suffix('123')     # => "abc"
'abc123'.delete_suffix!('123') # => "abc"

It's even significantly faster (almost 40% with the bang method) than the top answer. Here's the result of the same benchmark:

                     user     system      total        real
chomp 0.949823 0.001025 0.950848 ( 0.951941)
range 1.874237 0.001472 1.875709 ( 1.876820)
delete_suffix 0.721699 0.000945 0.722644 ( 0.723410)
delete_suffix! 0.650042 0.000714 0.650756 ( 0.651332)

I hope this is useful - note the method doesn't currently accept a regex so if you don't know the suffix it's not viable for the time being. However, as the accepted answer (update: at the time of writing) dictates the same, I thought this might be useful to some people.

what is the best way to remove the last n characters of a string (in Ruby)?

You can use ranges.

"string"[0..-4]

Remove the last 2 characters from a string in Ruby?

Use join:

def self.all_email_addresses
User.all.collect {|u| u.email}.join ', '
end

Extracting the last n characters from a ruby string

Here you have a one liner, you can put a number greater than the size of the string:

"123".split(//).last(5).to_s

For ruby 1.9+

"123".split(//).last(5).join("").to_s

For ruby 2.0+, join returns a string

"123".split(//).last(5).join

remove last character from looping Hash

I don't know actualy what your scenario But I base on your expected and You can try it.

total_user_input = [
"name:test",
"age:30"
]

input_length = total_user_input.size
total_user_input.each_with_index do |input, index|
aa = input.split(":").reduce {|first, second| " \t'#{first}': '#{second}',\r\n".gsub("'",'"') }
aa = aa.gsub(',', '') if index == input_length - 1 # or aa.slice(-1)
puts aa
end

=> My result

"name": "test",
"age": "30"

How do I remove the last line of a string that has visible characters in ruby?

Consider a string like the following (line breaks written as \n):

str = "Hello\nThere\nWorld!\n\n"

First, use String#strip to remove trailing whitespace, and use String#split to break the string into an array where each element represents one line of the string.

str = str.strip.split("\n")
#=> ["Hello", "There", "World!"]

You can then extract the last line from the last element in the array using Array#pop.

last_line = str.pop
#=> "World!"

Finally, use Array#join to re-assemble the array.

str = str.join("\n")
#=> "Hello\nThere"

Remove everything after some characters

This can be relatively easily accomplished by running split("More info") on your strings. What that does is breaks the string in to an array like so:

new_string  = "Posted today More info Go to Last Post"
new_string = new_string.split("More info")
# becomes ["Posted today ", " Go to Last Post"]

What split does is it breaks a string apart in to an array, where each element is what preceded the argument. So if you have "1,2,3" then split(",") will return [1, 2, 3]

So to continue your solution, you can get the posting date like this:

new_string[0].strip

.strip removes spaces at the front or back of a string, so you'll be left with just "Posted today"

How to mask all but last four characters in a string


positive lookahead

A positive lookahead makes it pretty easy. If any character is followed by at least 4 characters, it gets replaced :

"654321".gsub(/.(?=.{4})/,'#')
# "##4321"

Here's a description of the regex :

r = /
. # Just one character
(?= # which must be followed by
.{4} # 4 characters
) #
/x # free-spacing mode, allows comments inside regex

Note that the regex only matches one character at a time, even though it needs to check up to 5 characters for each match :

"654321".scan(r)
# => ["6", "5"]

/(.)..../ wouldn't work, because it would consume 5 characters for each iteration :

"654321".scan(/(.)..../)
# => [["6"]]
"abcdefghij".scan(/(.)..../)
# => [["a"], ["f"]]

If you want to parametrize the length of the unmasked string, you can use variable interpolation :

all_but = 4
/.(?=.{#{all_but}})/
# => /.(?=.{4})/

Code

Packing it into a method, it becomes :

def mask(string, all_but = 4, char = '#')
string.gsub(/.(?=.{#{all_but}})/, char)
end

p mask('testabcdef')
# '######cdef'
p mask('1234')
# '1234'
p mask('123')
# '123'
p mask('x')
# 'x'

You could also adapt it for sentences :

def mask(string, all_but = 4, char = '#')
string.gsub(/\w(?=\w{#{all_but}})/, char)
end

p mask('It even works for multiple words')
# "It even #orks for ####iple #ords"

Some notes about your code

string.to_s

Naming things is very important in programming, especially in dynamic languages.

string.to_s

If string is indeed a string, there shouldn't be any reason to call to_s.

If string isn't a string, you should indeed call to_s before gsub but should also rename string to a better description :

object.to_s
array.to_s
whatever.to_s

join

puts array.join(", ").delete(", ").inspect

What do you want to do exactly? You could probably just use join :

[1,2,[3,4]].join(", ").delete(", ")
# "1234"
[1,2,[3,4]].join
# "1234"

delete

Note that .delete(", ") deletes every comma and every whitespace, in any order. It doesn't only delete ", " substrings :

",a b,,,   cc".delete(', ')
# "abcc"
["1,2", "3,4"].join(', ').delete(', ')
# "1234"


Related Topics



Leave a reply



Submit