0

I need to extract from an input everything that is after a parameter.

  • Input: "-a Apple -b Ball -c Chocolate"
  • Criteria: Need to extract everything after -c.

My output should be Chocolate. I tried split, scan and the output returned two elements. Can anyone help me with this requirement?

Also, request you to let me know how to handle if my input is "-a Apple -c Chocolate -b Ball".

3
  • 1
    So for "-a Apple -c Chocolate -b Ball", you want " Chocolate -b Ball" (everything after -c), right? Commented Mar 28, 2016 at 20:10
  • no. If my input is "-a Apple -c Chocolate -b Ball", I still wanted to read only -c value as Chocolate. My concern was the position of the -c parameter in the input string. Commented Mar 28, 2016 at 22:26
  • That is not everything after -c. Commented Mar 29, 2016 at 3:34

4 Answers 4

2

You can use the OptionParser library to do this:

require 'optparse'

arguments = { }

opts = OptionParser.new do |parser|
  parser.on('-a=s') do |v|
    arguments[:a] = v
  end
  parser.on('-b=s') do |v|
    arguments[:b] = v
  end
  parser.on('-c=s') do |v|
    arguments[:c] = v
  end
end

opts.parse("-a Apple -b Ball -c Chocolate".split)

arguments
# => {:a=>"Apple", :b=>"Ball", :c=>"Chocolate"}

It's quite flexible in how it works, so you can define a lot of options and how they're interpreted.

Sign up to request clarification or add additional context in comments.

Comments

1

If you really want everything after the marker (-c):

s = "-a Apple -b Ball -c Chocolate"
index = s.index('-c')
everything_after = s[(index + 2)..-1]
puts everything_after # => Chocolate

If you want to parse the arguments:

require 'optparse'

opts = OptionParser.new do |parser|
  parser.on('-a=s') do |v|
  end
  parser.on('-b=s') do |v|
  end
  parser.on('-c=s') do |v|
    puts "-c is #{v}"
  end
end

opts.parse("-a Apple -b Ball -c Chocolate".split(/\s/))

(you will need to specify all the flags, otherwise the parser will choke)

Or you could simply match the content with a Regexp. I think you are looking for: <ANYTHING><FLAG><ANYTHING BUT DASH><ANYTHING> where <FLAG> is '-c '

s.match(/\A.*-c\s([^-]*).*\z/) do |match|
  p match[1]
end

Comments

0

Assuming that the input is the command line arguments passed to a ruby script, try:

ARGV[ARGV.index("-c") + 1]

Explanation:

ARGV is an array that includes all the arguments passed to a ruby script. Array#index returns the index of the first object in self.

Refer to Array#index for more info.

Comments

0
s = "-a Apple -b Ball -c Chocolate"

One way: calculate an index

marker = "-c"
s[s.index(marker)+marker.size+1..-1]
  #=> "Chocolate" 

marker = "-b"
s[s.index(marker)+marker.size+1..-1]
  #=> "Ball -c Chocolate" 

marker = "-a"
s[s.index(marker)+marker.size+1..-1]
  #=> "Apple -b Ball -c Chocolate" 

Another way: use a regex

`\K` in the regex below means "forget everything matched so far".

marker = "-c"
s[/#{marker}\s+\K.*/]
  #=> "Chocolate" 

marker = "-b"
s[/#{marker}\s+\K.*/]
  #=> "Ball -c Chocolate" 

marker = "-a"
s[/#{marker}\s+\K.*/]
  #=> "Apple -b Ball -c Chocolate" 

Consider the regex for one of these markers.

marker = "-a"
r = /
    #{marker}   # match the contents of the variable 'marker'
    \s+         # match > 0 whitespace chars
    \K          # forget everything matched so far
    .*          # match the rest of the line
    /x          # free-spacing regex definition mode
  #=> /
  #   -a          # match the contents of the variable 'marker'
  #   \s+         # match > 0 whitespace chars
  #   \K          # forget everything matched so far
  #   .*          # match the rest of the line
  #   /x 
s[r]
  #=> "Apple -b Ball -c Chocolate"

But if you really want just the text between markers

I will construct a hash with markers as keys and text as values. First, we will use the following regex to split the string.

r = /
      \s*     # match >= 0 spaces
      \-      # match hypen
      (       # begin capture group 1
        [a-z] # match marker
      )       # end capture group 1
        \s*   # match >= 0 spaces
      /x      # free-spacing regex definition mode

h = s.split(r).drop(1).each_slice(2).to_h
  #=> {"a"=>"Apple", "b"=>"Ball", "c"=>"Chocolate"} 

With this hash we can retrieve the text for each marker.

h["a"]
  #=> "Apple" 
h["b"]
  #=> "Ball" 
h["c"]
  #=> "Chocolate" 

The steps to create the hash are as follows.

a = s.split(r)
  #=> ["", "a", "Apple", "b", "Ball", "c", "Chocolate"] 

Notice that, by putting [a-z] within a capture group in the regex, "a", "b" and "c" are included in the array a. (See String#split, third paragraph.)

b = a.drop(1)
  #=> ["a", "Apple", "b", "Ball", "c", "Chocolate"] 
c = b.each_slice(2)
  #=> #<Enumerator: ["a", "Apple", "b", "Ball", "c", "Chocolate"]:each_slice(2)> 

We can see the elements of the enumerator c by converting it to an array:

c.to_a
  #=> [["a", "Apple"], ["b", "Ball"], ["c", "Chocolate"]] 

Lastly,

c.to_h
  #=> {"a"=>"Apple", "b"=>"Ball", "c"=>"Chocolate"} 

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.