字符串中的子串

时间:2016-03-28 20:01:33

标签: ruby string

我需要从输入中提取参数之后的所有内容。

  • 输入:"-a Apple -b Ball -c Chocolate"
  • 标准:需要在-c之后提取所有内容。

我的输出应为Chocolate。我尝试了splitscan,输出返回了两个元素。任何人都可以帮我解决这个问题吗?

另外,如果我的输入为"-a Apple -c Chocolate -b Ball",请您告诉我如何处理。

4 个答案:

答案 0 :(得分:2)

您可以使用OptionParser库执行此操作:

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

它的工作方式非常灵活,因此您可以定义很多选项以及如何解释它们。

答案 1 :(得分:1)

如果你真的想要标记后的所有内容(-c):

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

如果要解析参数:

要求' 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/))

(您需要指定所有标志,否则解析器会阻塞)

或者您可以简单地将内容与Regexp匹配。 我想你正在寻找:< ANYTHING>< FLAG>< ANTHTHING BUT DASH>< ANYTHING>其中< FLAG>是' -c'

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

答案 2 :(得分:0)

假设输入是传递给ruby脚本的命令行参数,请尝试:

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

说明:

ARGVarray,其中包含传递给ruby脚本的所有参数。 Array#index返回self中第一个对象的索引。

有关详细信息,请参阅Array#index

答案 3 :(得分:0)

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

单向:计算指数

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" 

另一种方式:使用正则表达式

`\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" 

考虑其中一个标记的正则表达式。

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"

但如果你真的只想要标记之间的文字

我将构造一个散列,其中标记为键,文本为值。首先,我们将使用以下正则表达式来拆分字符串。

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

使用此哈希,我们可以检索每个标记的文本。

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

创建哈希的步骤如下:

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

请注意,通过将[a-z]放入正则表达式中的捕获组,"a""b""c"包含在数组a中。 (见String#split,第三段。)

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)> 

我们可以通过将枚举器转换为数组来查看枚举器c的元素:

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

最后,

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