Print and display white spaces as characters - ruby

I've failed to work out how I can print and display white space characters as something that I can actually 'see'. So for example,
x = "123\n"
print x
I'd like the output to be
123\n
rather than
123
.
The above '.' represents the new line created by '\n'.

s = "abc\ndef"
p s
# >> "abc\ndef"
# it's equivalent to
puts s.inspect
# >> "abc\ndef"

You can do:
x = "123\n"
p x
#=> "123\n"
This method is documented in the Kernel module.

irb(main):003:0> x='123\n'
=> "123\\n"
irb(main):004:0> puts x
123\n
Works for me. Single quoted strings are unescaped, whilst double quoted strings are. To illustrate the difference, I've put the double quoted version below as well:
irb(main):001:0> x="123\n"
=> "123\n"
irb(main):002:0> puts x
123
=> nil

Related

How do you strip substrings in ruby?

I'd like to replace/duplicate a substring, between two delimeters -- e.g.,:
"This is (the string) I want to replace"
I'd like to strip out everything between the characters ( and ), and set that substr to a variable -- is there a built in function to do this?
I would just do:
my_string = "This is (the string) I want to replace"
p my_string.split(/[()]/) #=> ["This is ", "the string", " I want to replace"]
p my_string.split(/[()]/)[1] #=> "the string"
Here are two more ways to do it:
/\((?<inside_parenthesis>.*?)\)/ =~ my_string
p inside_parenthesis #=> "the string"
my_new_var = my_string[/\((.*?)\)/,1]
p my_new_var #=> "the string"
Edit - Examples to explain the last method:
my_string = 'hello there'
capture = /h(e)(ll)o/
p my_string[capture] #=> "hello"
p my_string[capture, 1] #=> "e"
p my_string[capture, 2] #=> "ll"
var = "This is (the string) I want to replace"[/(?<=\()[^)]*(?=\))/]
var # => "the string"
str = "This is (the string) I want to replace"
str.match(/\((.*)\)/)
some_var = $1 # => "the string"
As I understand, you want to remove or replace a substring as well as set a variable equal to that substring (sans the parentheses). There are many ways to do this, some of which are slight variants of the other answers. Here's another way that also allows for the possibility of multiple substrings within parentheses, picking up from #sawa's comments:
def doit(str, repl)
vars = []
str.gsub(/\(.*?\)/) {|m| vars << m[1..-2]; repl}, vars
end
new_str, vars = doit("This is (the string) I want to replace", '')
new_str # => => "This is I want to replace"
vars # => ["the string"]
new_str, vars = doit("This is (the string) I (really) want (to replace)", '')
new_str # => "This is I want"
vars # => ["the string", "really, "to replace"]
new_str, vars = doit("This (short) string is a () keeper", "hot dang")
new_str # => "This hot dang string is a hot dang keeper"
vars # => ["short", ""]
In the regex, the ? in .*? makes .* "lazy". gsub passes each match m to the block; the block strips the parens and adds it to vars, then returns the replacement string. This regex also works:
/\([^\(]*\)/

Reading a .txt file with escaped characters in Ruby

I'm having difficulty reading a file with escaped characters in Ruby...
My text file has the string "First Line\r\nSecond Line" and when I use File.read, I get a string back that escapes my escaped characters: "First Line\r\nSecond Line"
These two strings are not the same things...
1.9.2-p318 :006 > f = File.read("file.txt")
=> "First Line\\r\\nSecond Line"
1.9.2-p318 :007 > f.count('\\')
=> 2
1.9.2-p318 :008 > f = "First Line\r\nSecond Line"
=> "First Line\r\nSecond Line"
1.9.2-p318 :009 > f.count('\\')
=> 0
How can I get the File.read to not escape my escaped characters?
Create a method to remove all the additional escape characters that the File.Read method added, like this:
# Define a method to handle unescaping the escape characters
def unescape_escapes(s)
s = s.gsub("\\\\", "\\") #Backslash
s = s.gsub('\\"', '"') #Double quotes
s = s.gsub("\\'", "\'") #Single quotes
s = s.gsub("\\a", "\a") #Bell/alert
s = s.gsub("\\b", "\b") #Backspace
s = s.gsub("\\r", "\r") #Carriage Return
s = s.gsub("\\n", "\n") #New Line
s = s.gsub("\\s", "\s") #Space
s = s.gsub("\\t", "\t") #Tab
s
end
Then see it in action:
# Create your sample file
f = File.new("file.txt", "w")
f.write("First Line\\r\\nSecond Line")
f.close
# Use the method to solve your problem
f = File.read("file.txt")
puts "BEFORE:", f
puts f.count('\\')
f = unescape_escapes(f)
puts "AFTER:", f
puts f.count('\\')
# Here's a more elaborate use of it
f = File.new("file2.txt", "w")
f.write("He used \\\"Double Quotes\\\".")
f.write("\\nThen a Backslash: \\\\")
f.write('\\nFollowed by \\\'Single Quotes\\\'.')
f.write("\\nHere's a bell/alert: \\a")
f.write("\\nThis is a backspaces\\b.")
f.write("\\nNow we see a\\rcarriage return.")
f.write("\\nWe've seen many\\nnew lines already.")
f.write("\\nHow\\sabout\\ssome\\sspaces?")
f.write("\\nWe'll also see some more:\\n\\ttab\\n\\tcharacters")
f.close
# Read the file without the method
puts "", "BEFORE:"
puts File.read("file2.txt")
# Read the file with the method
puts "", "AFTER:"
puts unescape_escapes(File.read("file2.txt"))
You could just hack them back in.
foo = f.gsub("\r\n", "\\r\\n")
#=> "First Line\\r\\nSecond Line"
foo.count("\\")
#=> 2

Ruby string operate (delimeter)

I have a string like this:
14.015_KNECHT_178178
How can I split it so that:
art = 14.015
man = KNECHT
As you see the delimeter is _.
Try this
art,man= "14.015_KNECHT_178178".split(/_/)
for more details of #split here
string#split can do this.
>> (art,man,foo) = "14.015_KNECHT_178178".split '_'
=> ["14.015", "KNECHT", "178178"]
>> p art
"14.015"
=> "14.015"
>> p man
"KNECHT"
=> "KNECHT"
>> p foo
"178178"
=> "178178"

How to get all leading characters before the first instance of a number

I have product codes that look like:
abc123
abcd23423
I need to get all the leading characters before the first instance of a number, so:
abc
abcd
What's the best way to do this?
"abc123 abcd23423".scan(/(\D*)\d+/)
=> [["abc"], [" abcd"]]
"abc123 abcd23423".scan(/(\D*)\d+/).join
=> "abc abcd"
'abc123 abcd23423'.split(/\d+/).join
or just
'abc123 abcd23423'.gsub(/\d+/,'')
DATA.each do |l|
chars = l[/^([[:alpha:]]+)/, 1] # [:alpha:] = [a-zA-Z]
puts chars
end
__END__
abc123
abcd23423
# >> abc
# >> abcd
If you want to capture the alpha into an array do something like this:
ary = []
DATA.each do |l|
ary << l[/^([[:alpha:]]+)/, 1] # [:alpha:] = [a-zA-Z]
end
ary # => ["abc", "abcd"]
__END__
abc123
abcd23423
I didn't use \D because it means all non-numeric (AKA [^0-9]), but that can be dangerous if you are going to run into any other text that is not an alpha character:
'abc_-$%#123'[/^(\D+)/, 1] # => "abc_-$%#"
For the same reason \w is not necessarily safe:
'abc_-$%#123'[/^(\w+)/, 1] # => "abc_"
[[:alpha:]] is the alphabet characters [a-zA-Z]
'abc_-$%#123'[/^([a-zA-Z]+)/, 1] # => "abc"
'abc_-$%#123'[/^([[:alpha:]]+)/, 1] # => "abc"
You can use a regular expression which detects the beginning of the string (\A) and tries to capture as many non-digit characters (\D*) as possible (* is greedy by default):
processed_codes = codes.map { |code| code.scan(/\A(\D*)/)[0] }
You can also use String#match of course, but it has less predictable/intuitive behavior.

Setting end-of-line character for puts

I have an array of entries I would like to print.
Being arr the array, I used just to write:
puts arr
Then I needed to use the DOS format end-of-line: \r\n, so I wrote:
arr.each { |e| print "#{e}\r\n" }
This works correctly, but I would like to know if there is a way to specify what end-of-line format to use so that I could write something like:
$eol = "\r\n"
puts arr
UPDATE 1
I know that puts will use the correct line-endings depending on the platform it is run on, but I need this because I will write the output to a file.
UPDATE 2
As Mark suggested, setting $\ is useful. Anyway it just works for print.
For example,
irb(main):001:0> a = [1, 2, 3]
=> [1, 2, 3]
irb(main):002:0> $\ = "\r\n"
=> "\r\n"
irb(main):003:0> print a
123
=> nil
irb(main):004:0> puts a
1
2
3
=> nil
print prints all array items on a single line and then add $\, while I would like the behaviour of puts: adding $\ after each item of the array.
Is this possible at all without using Array#each?
The Ruby variable $\ will set the record separator for calls to print and write:
>> $\ = '!!!'
=> "!!!"
>> print 'hi'
hi!!!=> nil
Alternatively you can refer to $\ as $OUTPUT_RECORD_SEPARATOR if you import the English module.
Kernel#puts is equivalent to STDOUT.puts; and IO.puts "writes a newline after every element that does not already end with a newline sequence". So you're out of luck with pure puts for arrays. However, the $, variable is the separator string output between parameters suck as Kernel#print and Array#join. So if you can handle calling print arr.join, this might be the best solution for what you're doing:
>> [1,2,3].join
=> "123"
>> $, = '---'
=> "---"
>> [1,2,3].join
=> "1---2---3"
>> $\ = '!!!'
=> "!!!"
>> print [1,2,3].join
1---2---3!!!=> nil

Resources