The letter disapperaed after Splitting string in my ruby program - ruby

I am newbie in ruby. In my ruby program, there is a part of code for parsing geocode. The code is like below:
string = "GPS:3;S23.164865;E113.428970;88"
info = string.tr("GPS:",'')
info_array = info.split(";")
puts "GPS: #{info_array[0]},#{info_array[1]},#{info_array[2]}"
The code should split the string into 3 piece: 3, S23.164865 and E113.428970;88 and the expected output is
GPS: 3,S23.164865,E113.428970
but the result is:
GPS: 3,23.164865,E113.428970
Yes, the 'S' letter disappered...
If I use
string = "GPS:3;N23.164865;E113.428970;88"
info = string.tr("GPS:",'')
info_array = info.split(";")
puts "GPS: #{info_array[0]},#{info_array[1]},#{info_array[2]}"
, it prints expected result
GPS: 3,N23.164865,E113.428970
I am very confused why this happens. Can you help?

It looks like you were expecting String#tr to behave like String#gsub.
Calling string.tr("GPS:", '') does not replace the complete string "GPS:" with the empty string. Instead, it replaces any character from within the string "GPS:" with an empty string. Commonly you will find .tr() called with an equal number of input and replacement characters, and in that case the input character is replaced by the output character in the corresponding position. But the way you have called it with only the empty string '' as its translation argument, will delete any of G, P, S, : from anywhere within the string.
>> "String with S and G and a: P".tr("GPS:", '')
=> "tring with and and a "
Instead, use .gsub('GPS:', '') to replace the complete match as a group.
string = "GPS:3;S23.164865;E113.428970;88"
info = string.gsub('GPS:', '')
info_array = info.split(";")
puts "GPS: #{info_array[0]},#{info_array[1]},#{info_array[2]}"
# prints
GPS: 3,S23.164865,E113.428970
Here we've called .gsub() with a string argument. It is probably more often called with a regexp search match argument though.

Related

How to replace every 4th character of a string using .gsub in Ruby?

Beginner here, obviously. I need to add a sum and a string together and from the product, I have to replace every 4th character with underscore, the end product should look something like this: 160_bws_np8_1a
I think .gsub is the way, but I can find a way to format the first part in .gsub where I have to specify every 4th character.
total = (1..num).sum
final_output = "#{total.to_s}" + "06bwsmnp851a"
return final_output.gsub(//, "_")
This would work:
s = '12345678901234'
s.gsub(/(...)./, '\1_')
#=> "123_567_901_34"
The regex matches 3 characters (...) that are captured (parentheses) followed by another character (.). Each match is replaced by the first capture (\1) and a literal underscore (_).
s = "12345678901234"
Here are two ways to do that. Both return
"123_567_901_34"
Match every four-character substring and replace the match with the first three characters of the match followed by an underscore
s.gsub(/.{4}/) { |s| s[0,3] << '_' }
Chain the enumerator s.gsub(/./) to Enumerator#with_index and replace every fourth character with an underscore
s.gsub(/./).with_index { |c,i| i%4 == 3 ? '_' : c }
See the form of String#gsub that takes a single argument and no block.

Split String( String contains Regular expression)

I want to split the last string from given path, that string contains some numbers like 1.625.235, but this numbers vary every time. Irrespective of the number that last string should be split.
Ex:
string = "C:/chef/cache/Dynatrace-OneAgent-Windows-1.625.235.msi"
output: Dynatrace-OneAgent-Windows-1.625.235.msi
string = "C:/chef/cache/Dynatrace-OneAgent-Windows-1.181.539.msi"
output: Dynatrace-OneAgent-Windows-1.181.539.msi
This is what we tried
("C:/chef/cache/Dynatrace-OneAgent-Windows-/\d.\d+.\d+/.msi").split('/')[3]
("C:/chef/cache/Dynatrace-OneAgent-Windows-'/\d.\d+.\d+/'.msi").split('/')[3]
("C:/chef/cache/Dynatrace-OneAgent-Windows-'\d.\d+.\d+'.msi").split('/')[3]
("C:/chef/cache/Dynatrace-OneAgent-Windows-'(\d.\d+.\d+').msi").split('/')[3]
("C:/chef/cache/Dynatrace-OneAgent-Windows-('/\d.\d+.\d+/').msi").split('/')[3]
("C:/chef/cache/Dynatrace-OneAgent-Windows-('\d.\d+.\d+').msi").split('/')[3]
If the output you want is always the filename at the end of a path, you could also use File.basename.
string = "C:/chef/cache/Dynatrace-OneAgent-Windows-1.625.235.msi"
output = File.basename(string) # => "Dynatrace-OneAgent-Windows-1.625.235.msi"
string="C:/chef/cache/Dynatrace-OneAgent-Windows-1.625.235.msi"
p string.split("/").last
output
"Dynatrace-OneAgent-Windows-1.625.235.msi"

string capture between duplicates in ruby

string = 'xabcdexfghijk'
In the example above, 'x' appears twice. I want to capture everything between the first 'x' and the next 'x'. Thus, the desired result is a new string that equals 'xabcdex'. Any ideas?
You could use a simple regular expression: /x.*?x/. This basically means "match any characters in between two x characters, as few times as possible (non-greedy)".
The matched text can be extracted with String#[regexp]
string = 'xabcdexfghijk'
string[/x.*?x/] # => "xabcdex"

Remove email address from string in Ruby

I have the following code which is supposed to be removing a particular email address from a string if it exists. The problem is i get the error "invalid range "y-d" in string transliteration (ArgumentError)" which I assume is because it's treating my input as a regex. I will need to do this delete by a variable in the actual code, not a string literal but this is a simplified version of the problem.
So how do I properly perform this operation?
myvar = "test1#my-domain.com test2#my-domain.com"
myvar = myvar.delete("test1#my-domain.com")
Try
myvar = "test1#my-domain.com test2#my-domain.com"
myvar = myvar.gsub("test1#my-domain.com", '').strip
String#delete(str) does not delete the literal string str but builds a set out of individual characters of str and deletes all occurrences of these characters. try this:
"sets".delete("test")
=> ""
"sets".delete("est")
=> ""
The hyphen has a special meaning, it defines a range of characters. String#delete("a-d") will delete all occurrences of a,b,c and d characters. Range boundary characters should be given in ascending order: you should write "a-d" but not "d-a".
In your original example, ruby tries to build a character range from y-d substring and fails.
Use String#gsub method instead.
You can do it like this
myvar = "test1#my-domain.com test2#my-domain.com"
remove = "test1#my-domain.com"
myvar.gsub!(remove, "")

Why doesn't this Ruby replace regex work as expected?

Consider the following string which is a C fragment in a file:
strcat(errbuf,errbuftemp);
I want to replace errbuf (but not errbuftemp) with the prefix G-> plus errbuf. To do that successfully, I check the character after and the character before errbuf to see if it's in a list of approved characters and then I perform the replace.
I created the following Ruby file:
line = " strcat(errbuf,errbuftemp);"
item = "errbuf"
puts line.gsub(/([ \t\n\r(),\[\]]{1})#{item}([ \t\n\r(),\[\]]{1})/, "#{$1}G\->#{item}#{$2}")
Expected result:
strcat(G->errbuf,errbuftemp);
Actual result
strcatG->errbuferrbuftemp);
Basically, the matched characters before and after errbuf are not reinserted back with the replace expression.
Anyone can point out what I'm doing wrong?
Because you must use syntax gsub(/.../){"...#{$1}...#{$2}..."} or gsub(/.../,'...\1...\2...').
Here was the same problem: werid, same expression yield different value when excuting two times in irb
The problem is that the variable $1 is interpolated into the argument string before gsub is run, meaning that the previous value of $1 is what the symbol gets replaced with. You can replace the second argument with '\1 ?' to get the intended effect. (Chuck)
I think part of the problem is the use of gsub() instead of sub().
Here's two alternates:
str = 'strcat(errbuf,errbuftemp);'
str.sub(/\w+,/) { |s| 'G->' + s } # => "strcat(G->errbuf,errbuftemp);"
str.sub(/\((\w+)\b/, '(G->\1') # => "strcat(G->errbuf,errbuftemp);"

Resources