# code
ENV['VAR_1'] = 'HELLO 1'
ENV['VAR_2'] = 'HELLO 2'
ENV['VAR_3'] = 'HELLO 3'
# code
How do I extract using ruby and regex each variable and it's value?
Currently I'm doing line by line which is stupid.
S3_SECRET = line.split(' = ').last.delete("'") if line =~ /ENV\['S3_SECRET'\]/
S3_KEY = line.split(' = ').last.delete("'") if line =~ /ENV\['S3_KEY'\]/
S3_BUCKET = line.split(' = ').last.delete("'") if line =~ /ENV\['S3_BUCKET'\]/
You may have quite a verbose regex like
/^ENV\['(.*?)'\] *= *'(.*?)'$/
See the regex demo.
Details:
^ - start of line
ENV\[' - a literal ENV[' substring
(.*?) - Group 1 capturing 0+ chars other than a newline as few as possible up to the first
'\] - literal '] text
*= * - a = sign enclosed with optional (0 or more) spaces
' - a single quote
(.*?) - Group 2 capturing 0+ chars other than a newline as few as possible up to the
' - final ' at...
$ - the end of the line.
Here is a Ruby demo:
s = <<DATA
# code
ENV['VAR_1'] = 'HELLO 1'
ENV['VAR_2'] = 'HELLO 2'
ENV['VAR_3'] = 'HELLO 3'
# code
DATA
puts s.scan(/^ENV\['(.*?)'\] *= *'(.*?)'$/).to_h
Output: {"VAR_1"=>"HELLO 1", "VAR_2"=>"HELLO 2", "VAR_3"=>"HELLO 3"}
Suppose you've read the file into an array of lines (using, say, IO#readlines).
arr = ["ENV['VAR_1'] = 'HELLO 1'",
"ENV['VAR_2'] = 'HELLO 2'",
"ENV['VAR_3'] = 'HELLO 3'"]
Rather than using a complex regex straight away, we can remove the text we don't want, split the slimed-down strings on "=", surrounded by spaces, and then convert the resultant array to a hash.
bad_bits = %w| ENV[ ] ' |
#=> ["ENV[", "]", "'"]
r = Regexp.union(bad_bits)
#=> /ENV\[|\]|'/
arr.map { |str| str.gsub(r, '') }.map { |s| s.split(/\s+=\s+/) }.to_h
#=> {"VAR_1"=>"HELLO 1", "VAR_2"=>"HELLO 2", "VAR_3"=>"HELLO 3"}
Notice that Regexp::union does the escaping of regex's special characters for you.
Related
I am trying to remove words that have more that have the same letter more than once. I have tried squeeze but all that is doing is removing words that have duplicate letters next to each other.
Here is the code at the moment:
array = []
File.open('word.txt').each do |line|
if line.squeeze == line
array << line
end
end
Input from word.txt
start
james
hello
joins
regex
Output that I am looking for
james
joins
Any suggestions on how I can get around this.
Perhaps something like this:
array = []
File.open('word.txt').each do |line|
chars = line.chars
array << line if chars.uniq == chars
end
or shorter:
array = File.open('word.txt').select { |word| word.chars.uniq == word.chars }
You could use a regular expression, for example:
re = /
(.) # match and capture a single character
.*? # any number of characters in-between (non-greedy)
\1 # match the captured character again
/x
Example:
'start'[re] #=> "tart"
'james'[re] #=> nil
'hello'[re] #=> "ll"
'joins'[re] #=> nil
'regex'[re] #=> "ege"
It can be passed to grep to return all matched lines:
IO.foreach('word.txt').grep(re)
#=> ["start\n", "hello\n", "regex\n"]
or to grep_v to return the other lines:
IO.foreach('word.txt').grep_v(re)
#=> ["james\n", "joins\n"]
a=[
helloworld:
prodValue:
version:7
class:[
ratio:
value: ""
stackOverflow:
version:3
]
#Inspect Output
"helloworld:"
"prodValue:"
"version:7"
"class:["
"ratio:"
"value: """
"stackOverflow:"
"version:3"
I want to print the previous word if the next word is version. Is there any ruby method to split the previous word if it detects some string ? I am using the following ruby script
a.delete("\n").delete(":").gsub(/\s+/,'').split('version:',-1)
remember the previous line and only output if it matches your criteria.
previous_line = ""
File.foreach(input_file) do |line|
puts previous_line if line.include? 'version:'
previous_line = line
end
To store this in an array:
previous_line = ""
detected_vals = []
File.foreach(input_file) do |line|
detected_vals << previous_line if line.include? 'version:'
previous_line = line
end
puts detected_vals.inspect
I've been using the following code for the problem. I'm making a program to change the IUPAC name into structure, so i want to analyse the string entered by the user.In IUPAC name there are brackets as well. I want to extract the compound name as per the brackets. The way I have shown in the end.
I want to modify the way such that the output comes out to be like this and to be stored in an array :
As ["(4'-cyanobiphenyl-4-yl)","5-[(4'-cyanobiphenyl-4-yl)oxy]",
"({5-[(4'-cyanobiphenyl-4-yl)oxy]pentyl}" .... and so on ]
And the code for splitting which i wrote is:
Reg_bracket=/([^(){}\[\]]*)([(){}\[\]])/
attr_reader :obrk, :cbrk
def count_level_br
#xbrk=0
#cbrk=0
if #temp1
#obrk+=1 if #temp1[1]=="(" || #temp1[1]=="[" ||#temp1[1]=="{"
#obrk-=1 if #temp1[1]==")" || #temp1[1]=="]" ||#temp1[1]=="}"
end
puts #obrk.to_s
end
def split_at_bracket(str=nil) #to split the brackets according to Regex
if str a=str
else a=self
end
a=~Reg_bracket
if $& #temp1=[$1,$2,$']
end
#temp1||=[a,"",""]
end
def find_block
#obrk=0 , r=""
#temp1||=["",""]
split_at_bracket
r<<#temp1[0]<<#temp1[1]
count_level_br
while #obrk!=0
split_at_bracket(#temp1[2])
r<<#temp1[0]<<#temp1[1]
count_level_br
puts r.to_s
if #obrk==0
puts "Level 0 has reached"
#puts "Close brackets are #{#cbrk}"
return r
end
end #end
end
end #class end'
I ve used the regex to match the brackets. And then when it finds any bracket it gives the result of before match, after match and second after match and then keeps on doing it until it reaches to the end.
The output which I m getting right now is this.
1
2
1-[(
3
1-[({
4
1-[({5-[
5
1-[({5-[(
4
1-[({5-[(4'-cyanobiphenyl-4-yl)
3
1-[({5-[(4'-cyanobiphenyl-4-yl)oxy]
2
1-[({5-[(4'-cyanobiphenyl-4-yl)oxy]pentyl}
1
1-[({5-[(4'-cyanobiphenyl-4-yl)oxy]pentyl}oxy)
0
1-[({5-[(4'-cyanobiphenyl-4-yl)oxy]pentyl}oxy)carbonyl]
Level 0 has reached
testing ends'
I have written a simple program to match the string using three different regular expressions. The first one will help separate out the parenthesis, the second will separate out the square brackets and the third will give the curly braces. Here is the following code. I hope you will be able to use it in your program effectively.
reg1 = /(\([a-z0-9\'\-\[\]\{\}]+.+\))/ # for parenthesis
reg2 = /(\[[a-z0-9\'\-\(\)\{\}]+.+\])/ # for square brackets
reg3 = /(\{[a-z0-9\'\-\(\)\[\]]+.+\})/ # for curly braces
a = Array.new
s = gets.chomp
x = reg1.match(s)
a << x.to_s
str = x.to_s.chop.reverse.chop.reverse
while x != nil do
x = reg1.match(str)
a << x.to_s
str = x.to_s.chop
end
x = reg2.match(s)
a << x.to_s
str = x.to_s.chop.reverse.chop.reverse
while x != nil do
x = reg2.match(str)
a << x.to_s
str = x.to_s.chop
end
x = reg3.match(s)
a << x.to_s
str = x.to_s.chop.reverse.chop.reverse
while x != nil do
x = reg3.match(str)
a << x.to_s
str = x.to_s.chop
end
puts a
The output is a follows :
ruby reg_yo.rb
4,4'{-1-[({5-[(4'-cyanobiphenyl-4-yl)oxy]pentyl}oxy)carbonyl]-2-[(4'-cyanobiphenyl-4-yl)oxy]ethylene}dihexanoic acid # input string
({5-[(4'-cyanobiphenyl-4-yl)oxy]pentyl}oxy)carbonyl]-2-[(4'-cyanobiphenyl-4-yl)
(4'-cyanobiphenyl-4-yl)oxy]pentyl}oxy)
(4'-cyanobiphenyl-4-yl)
[({5-[(4'-cyanobiphenyl-4-yl)oxy]pentyl}oxy)carbonyl]-2-[(4'-cyanobiphenyl-4-yl)oxy]
[(4'-cyanobiphenyl-4-yl)oxy]pentyl}oxy)carbonyl]
[(4'-cyanobiphenyl-4-yl)oxy]
{-1-[({5-[(4'-cyanobiphenyl-4-yl)oxy]pentyl}oxy)carbonyl]-2-[(4'-cyanobiphenyl-4-yl)oxy]ethylene}
{5-[(4'-cyanobiphenyl-4-yl)oxy]pentyl}
Update : I have modified the code so as to search for recursive patterns.
I'm trying to have greentext support for my Rails imageboard (though it should be mentioned that this is strictly a Ruby problem, not a Rails problem)
basically, what my code does is:
1. chop up a post, line by line
2. look at the first character of each line. if it's a ">", start the greentexting
3. at the end of the line, close the greentexting
4. piece the lines back together
My code looks like this:
def filter_comment(c) #use for both OP's and comments
c1 = c.content
str1 = '<p class = "unkfunc">' #open greentext
str2 = '</p>' #close greentext
if c1 != nil
arr_lines = c1.split('\n') #split the text into lines
arr_lines.each do |a|
if a[0] == ">"
a.insert(0, str1) #add the greentext tag
a << str2 #close the greentext tag
end
end
c1 = ""
arr_lines.each do |a|
strtmp = '\n'
if arr_lines.index(a) == (arr_lines.size - 1) #recombine the lines into text
strtmp = ""
end
c1 += a + strtmp
end
c2 = c1.gsub("\n", '<br/>').html_safe
end
But for some reason, it isn't working! I'm having weird things where greentexting only works on the first line, and if you have greentext on the first line, normal text doesn't work on the second line!
Side note, may be your problem, without getting too in depth...
Try joining your array back together with join()
c1 = arr_lines.join('\n')
I think the problem lies with the spliting the lines in array.
names = "Alice \n Bob \n Eve"
names_a = names.split('\n')
=> ["Alice \n Bob \n Eve"]
Note the the string was not splited when \n was encountered.
Now lets try this
names = "Alice \n Bob \n Eve"
names_a = names.split(/\n/)
=> ["Alice ", " Bob ", " Eve"]
or This "\n" in double quotes. (thanks to Eric's Comment)
names = "Alice \n Bob \n Eve"
names_a = names.split("\n")
=> ["Alice ", " Bob ", " Eve"]
This got split in array. now you can check and append the data you want
May be this is what you want.
def filter_comment(c) #use for both OP's and comments
c1 = c.content
str1 = '<p class = "unkfunc">' #open greentext
str2 = '</p>' #close greentext
if c1 != nil
arr_lines = c1.split(/\n/) #split the text into lines
arr_lines.each do |a|
if a[0] == ">"
a.insert(0, str1) #add the greentext tag
# Use a.insert id you want the existing ">" appended to it <p class = "unkfunc">>
# Or else just assign a[0] = str1
a << str2 #close the greentext tag
end
end
c1 = arr_lines.join('<br/>')
c2 = c1.html_safe
end
Hope this helps..!!
I'm suspecting that your problem is with your CSS (or maybe HTML), not the Ruby. Did the resulting HTML look correct to you?
I have someone entering a form with some string input. What I need to do is replace any white space in the string with " AND " (no quotes). What's the best way to do this?
Also, how would I go about doing this if I wanted to remove all the whitespace in the string?
Thanks
to replace with and:
s = 'this has some whitespace'
s.gsub! /\s+/, ' AND '
=> "this AND has AND some AND whitespace"
to remove altogether:
s = 'this has some whitespace'
s.gsub! /\s+/, ''
=> "thishassomewhitespace"
Split and join is another technique:
s = " a b c "
s.split(' ').join(' AND ')
# => "a AND b AND c"
This has the advantage of ignoring leading and trailing whitespace that Peter's RE does not:
s = " a b c "
s.gsub /\s+/, ' AND '
# => " AND a AND b AND c AND "
Removing whitespace
s.split(' ').join('')
# or
s.delete(' ') # only deletes space chars
use gsub method for replacing whitespace
s = "ajeet soni"
=> "ajeet soni"
s.gsub(" "," AND ")
=> "ajeet AND soni"