Tom Lehman
Tom Lehman

Reputation: 89203

How do I remove the first n lines from a string in Ruby?

One\n
Two\n
Three\n
Four\n

remove_lines(2) would remove the first two lines, leaving the string:

Three\n
Four\n

Upvotes: 22

Views: 18276

Answers (7)

retrography
retrography

Reputation: 6812

Here is a pure regexp one-liner. Hypothetically it should be even faster than the elegant solution provided by @DigitalRoss:

n = 4 # number of lines
str.gsub(/\A(.*\n){#{n}}/,'')

If you know in advance how many line you want to cut (4 here):

str.gsub(/\A(.*\n){4}/,'')

And if you want to cut only one line:

str.gsub(/\A.*\n/,'')

In order to cut n lines from the tail:

gsub(/(\n.*){#{n}}\Z/,'')

Upvotes: 2

Andrew
Andrew

Reputation: 238697

s = "One\nTwo\nThree\nFour"

lines = s.lines
> ["One\n", "Two\n", "Three\n", "Four"]

remaining_lines = lines[2..-1]
> ["Three\n", "Four"]

remaining_lines.join
> "Three\nFour"
  • String#lines converts the string into an array of lines (retaining the new line character at the end of each string)
  • [2..-1] specifies the range of lines to return, in this case the third through the last
  • Array#join concatenates the lines back together, without any space (but since the lines still contain the new line character, we don't need a separator)

In one line:

s.lines[2..-1].join

Upvotes: 8

cbrisket
cbrisket

Reputation: 87

I had a situation where I needed to support multiple platform EOLN (both \r and \n), and had success with the following:

split(/\r\n|\r|\n/, 2).last

Or the equivalent remove_lines:

def remove_lines(number_of_lines=1)
  split(/\r\n|\r|\n/, number_of_lines+1).last
end

Upvotes: 3

NawaMan
NawaMan

Reputation: 25687

This problem will remove the first two lines using regular expression.

Text = "One\nTwo\nThree\nFour"
Text = Text.gsub /^(?:[^\n]*\n){2}/, ''
# -----------------------------------^^  (2) Replace with nothing
# ----------------^^^^^^^^^^^^^^^^       (1) Detect first 2 lines
puts Text

EDIT: I've just saw that the question is also about 'n' lines not just two lines.

So here is my new answer.

Lines_Removed = 2
Original_Text = "One\nTwo\nThree\nFour"
Result___Text = (Original_Text.gsub(Regexp.new("([^\n]*\n){%s}" % Lines_Removed), ''))
#                                               ^^^^^^^^^^^^^^                    ^^
# - (1) Detect first  lines -----++++++++++++++                    ||
# - (2) Replace with nothing -----------------------------------------------------++

puts Result___Text # Returns "Three\nFour"

Upvotes: 1

DigitalRoss
DigitalRoss

Reputation: 146043

s.to_a[2..-1].join

>> s = "One\nTwo\nThree\nFour\n"
=> "One\nTwo\nThree\nFour\n"
>> s.to_a[2..-1].join
=> "Three\nFour\n"

Upvotes: 42

Overdose
Overdose

Reputation: 1500

def remove_lines(str, n)
  res = ""
  arr = str.split("\n")[n..(str.size-n)]
  arr.each { |i| res.concat(i + "\n")  }
  return res
end

a = "1\n2\n3\n4\n"
b = remove_lines(a, 2)
print b

Upvotes: 0

Koraktor
Koraktor

Reputation: 42913

class String

  def remove_lines(i)
    split("\n")[i..-1].join("\n")
  end

end

Calling "One\nTwo\nThree\nFour\n".remove_lines(2) would result in "Three\nFour". If you need the trailing "\n" you need to extend this method accordingly.

Upvotes: 5

Related Questions