Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Replacing "\n" but not "\n\n"

Tags:

ruby

gsub

How to replace "\n" but not "\n\n" etc. with " \n"?

text1 = "Hello\nWorld"
text1.sub! "\n", "  \n"
=> "Hello  \nWorld"

text2 = "Hello\n\nWorld"
text2.sub! "\n\n", "  \n"
=> "Hello  \n\nWorld"
SHOULD BE: => "Hello\n\nWorld"
like image 878
Flynt Hamlock Avatar asked Dec 03 '22 17:12

Flynt Hamlock


2 Answers

You can use the regular expression /(?<!\n)\n(?!\n)/, which matches a \n only when it's not prefixed with another \n and not followed by a \n.

text1 = "Hello\nWorld"
# => "Hello\nWorld"
text1.sub /(?<!\n)\n(?!\n)/, "  \n"
# => "Hello  \nWorld"
text2 = "Hello\n\nWorld"
# => "Hello\n\nWorld"
text2.sub /(?<!\n)\n(?!\n)/, "  \n"
# => "Hello\n\nWorld"
like image 112
Yu Hao Avatar answered Jan 05 '23 19:01

Yu Hao


Here's another way:

r = /\n+/

"Hello\nWorld".sub(r) { |s| (s.size==1) ? " \n" : s }
  #=> "Hello  \nWorld"

"Hello\n\nWorld".sub(r) { |s| (s.size==1) ? " \n" : s }
  #=> "Hello\n\nWorld"

and one more:

h = Hash.new { |h,k| h[k] = k }.update("\n"=>"  \n")
  #=> {"\n"=>"  \n"}

"Hello\nWorld".sub(r,h)
   #=> "Hello  \nWorld" 
"Hello\n\nWorld".sub(r,h)
   #=> "Hello\n\nWorld" 

In the latter method, each string of one or more consecutive newline characters is passed to the hash. If it's a single newline, "\n" is replaced with h["\n"] #=> " \n". If it's two or more newlines, say s = "\n\n", and h does not have a key equal to s (initally it won't), the key-value pair s=>s will be added to h (because of the default value defined for the hash) and s will be replaced by itself.

like image 42
Cary Swoveland Avatar answered Jan 05 '23 21:01

Cary Swoveland