Alex. b
Alex. b

Reputation: 689

Extract env variables from file using regex

# 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'\]/

Upvotes: 3

Views: 2589

Answers (2)

Cary Swoveland
Cary Swoveland

Reputation: 110725

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.

Upvotes: 1

Wiktor Stribiżew
Wiktor Stribiżew

Reputation: 627082

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"}

Upvotes: 2

Related Questions