How do I remove all characters in a string until a substring is matched, in Ruby?

20,004

Solution 1

or with the regex:

str = "Hey what's up @dude, @how's it going?"
str.gsub!(/.*?(?=@how)/im, "") #=> "@how's it going?"

you can read about lookaround at here

Solution 2

Use String#slice

s = "Hey what's up @dude, @how's it going?"
s.slice(s.index("@how")..-1)
# => "@how's it going?"

Solution 3

There are literally tens of ways of doing this. Here are the ones I would use:

If you want to preserve the original string:

str = "Hey what's up @dude, @how's it going?"
str2 = str[/@how's.+/mi]
p str, str2
#=> "Hey what's up @dude, @how's it going?"
#=> "@how's it going?"

If you want to mutate the original string:

str = "Hey what's up @dude, @how's it going?"
str[/\A.+?(?=@how's)/mi] = ''
p str
#=> "@how's it going?"

...or...

str = "Hey what's up @dude, @how's it going?"
str.sub! /\A.+?(?=@how's)/mi, ''
p str
#=> "@how's it going?"

You need the \A to anchor at the start of the string, and the m flag to ensure that you are matching across multiple lines.

Perhaps simplest of all for mutating the original:

str = "Hey what's up @dude, @how's it going?"
str.replace str[/@how's.+/mi]
p str
#=> "@how's it going?"

Solution 4

String#slice and String#index work fine but will blow up with ArgumentError: bad value for range if the needle is not in the haystack.

Using String#partition or String#rpartition might work better in that case:

s.partition "@how's"
# => ["Hey what's up @dude, ", "@how's", " it going?"]
s.partition "not there"
# => ["Hey what's up @dude, @how's it going?", "", ""]
s.rpartition "not there"
# => ["", "", "Hey what's up @dude, @how's it going?"]

Solution 5

An easy way to get only the part you are interested in.

>> s="Hey what's up @dude, @how's it going?"
=> "Hey what's up @dude, @how's it going?"
>> s[/@how.*$/i]
=> "@how's it going?"

If you really need to change the string object, you could always do s=s[...].

Share:
20,004
oxo
Author by

oxo

Updated on July 25, 2022

Comments

  • oxo
    oxo almost 2 years

    Say I have a string: Hey what's up @dude, @how's it going?

    I'd like to remove all the characters before@how's.

  • McStretch
    McStretch about 13 years
    +1 very clean. Aren't the indices off though? Shouldn't it be 0..s.index("@how")?
  • Simone Carletti
    Simone Carletti about 13 years
    He wants to strip everything before the match, that is the same to say "keep everything after the match".
  • oxo
    oxo about 13 years
    Considering that it could be in any case variation of @how (e.g. @How, @HOW, @HoW etc), could it be done like this: str.gsub(/.*?(?=@[Hh][Oo][Ww])/, "")?
  • McStretch
    McStretch about 13 years
    Oh whoops, I misunderstood how splice worked. I thought it removed the string in place, like a delete method. I didn't realize it returned the spliced text for use.
  • oxo
    oxo about 13 years
    I commented below to another answer, but I was wondering that since it could be in any case variation of @how (e.g. @How, @HOW, @HoW etc), could it be done like this: str.slice(str.index("@[Hh][Oo][Ww]")..-1)
  • Nathan Long
    Nathan Long about 13 years
    If the search string doesn't appear, the index will return nil. So he should either check for nil before doing the slice, or plan to rescue the error that comes from passing an index of nil to slice.
  • Vasiliy Ermolovich
    Vasiliy Ermolovich about 13 years
    sure, fixed. (/i have been added)
  • Phrogz
    Phrogz about 13 years
    No need for gsub! when sub! will do, right? Also note (per my answer) that you need the \A anchor and/or m flag in case the string has a newline before the text to match.
  • Phrogz
    Phrogz about 13 years
    You need a m flag on that last regex to match any newlines that may follow.
  • Vasiliy Ermolovich
    Vasiliy Ermolovich about 13 years
    Thanks! Sorry, I don't know the difference between gsub and sub. Could you explain it?
  • Andrew Haust
    Andrew Haust over 6 years
    Suuuuper old and you obviously probably know the difference by now, but would be nice to see the answer changed for n00bs: gsub does a global search and replace while sub stops after the first match. gsub could cause unexpected results or poor performance is longer strings.