views:

4570

answers:

6

I have a script written in ruby. I need to remove any duplicate newlines (e.g.)

\n
\n
\n

to

\n

My current attempt worked (or rather not) using

str.gsub!(/\n\n/, "\n")

Which gave me no change to the output. What am I doing wrong?

+2  A: 

are you sure it shouldn't be /\n\n\n/, "\n" that what you seem to be wanting in your question above.

also, are you sure it's not doing a windows new-line "\r\n"?

EDIT: Additional info

Per Comment

"The amount of newlines can change. Different lines have between 2 and 5 newlines."

if you only want to hit the 2-5 lines try this

/\n{2,5}/, "\n"
Keng
The amount of newlines can change. Different lines have between 2 and 5 newlines.
Macha
+5  A: 

Simply splitting and recombining the lines will give the desired result

>> "one\ntwo\n\nthree\n".split.join("\n")
=> "one\ntwo\nthree"

Edit: I just noticed this will replace ALL whitespace substrings with newlines, e.g.

>> "one    two three\n".split.join("\n")
=> "one\ntwo\nthree"

First check that this is what you want!

finnw
nice one - that is great way to do it!
Brian
Thanks, I selected this as the answer but then realised it splits on spaces too, which isn't good in my case. Sorry about that.
Macha
You're right. You could use str.split(/\n+/) but Chas. Owens' solution is simpler.
finnw
+7  A: 

This works for me:

#!/usr/bin/ruby

$s = "foo\n\n\nbar\nbaz\n\n\nquux";

puts $s

$s.gsub!(/[\n]+/, "\n");

puts $s
Chas. Owens
Why the brackets?
glenn jackman
Since that was a year ago, I have no idea. I expect that I tried /\n+/, as that is what I would use in Perl, and it didn't work for me, probably because I did something else wrong.
Chas. Owens
A: 

Ruby needs the backslashes escaped differently than you have provided.

str.sub!("\\\\n+\\\\n","\\\\n")

http://www.ruby-forum.com/topic/176239

Chris Ballance
+2  A: 

Simply calling split will also trim out all of your whitespace.

You need to pass \n to split

>> "one   ok \ntwo\n\nthree\n".split(/\n+/).join("\n")
=> "one  ok \ntwo\nthree"
Brian R. Bondy
+4  A: 

You need to match more than one newline up to an infinite amount. Your code example will work with just a minor tweak:

str.gsub!(/\n+/, "\n")

For example:

str = "this\n\n\nis\n\n\n\n\na\ntest"
str.gsub!(/\n+/, "\n")  # => "this\nis\na\ntest"
Peter Cooper