2014-02-20 155 views
0

我想用Ruby的OptionParser来解析命令行参数。我的一个参数是我定义这样不区分大小写OptionParser

opts.on('-p', '--project-name PROJECT', PROJECTS, 'The Project name', "{#{PROJECTS.join ', '}}"){|p| options.project = p} 

其中PROJECTS是一个字符串的预定义列表(我是红宝石1.8.7)接受字符串的预定义列表。我如何告诉OptionsParser应该使用POJECTS列表以不区分大小写的方式匹配参数?我看到类OptionParser :: List可能有这样的东西,我只是不知道如何使用它。

回答

1

您可以通过Regexp而不是PROJECTS阵列。该i修改在最后使得它不区分大小写:

/#{Regexp.union(PROJECTS).source}/i 
#=> /foo|bar|baz/i 

这里是一个完整的工作示例:

require 'optparse' 

options = Struct.new(:project).new 

PROJECTS = %w{foo bar baz} 
ALLOWED_PROJECTS = /#{Regexp.union(PROJECTS).source}/i 

OptionParser.new do |opts| 
    opts.on('-p', '--project-name PROJECT', ALLOWED_PROJECTS, 'The Project name', "{#{PROJECTS.join ', '}}") do |p| 
    options.project = p 
    end 
end.parse! 

p options 

用法:

$ ruby foo.rb -p foo 
#<struct project="foo"> 

$ ruby foo.rb -p FOO 
#<struct project="FOO"> 

$ ruby foo.rb -p bar 
#<struct project="bar"> 

$ ruby foo.rb -p bAz 
#<struct project="baz"> 

$ ruby foo.rb -p quux 
foo.rb:16:in `<main>': invalid argument: -p quux (OptionParser::InvalidArgument) 
+0

不要你的意思'Regexp.union(项目)'而不是那个地图/ escape/stringify/join/regexify的东西? –

+1

@ muistooshort我曾尝试过'Regexp.union',但那么您如何使得到的正则表达式不区分大小写?如果你做'/#{Regexp.union PROJECTS}/i',你会得到匹配区分大小写的'/(? - mix:foo | bar | baz)/ i',因为混合的正则表达式有自己的修饰符。我能想到的唯一选择是'Regexp.union PROJECTS.map {| p | /#{p}/i}'这并不会更好,并且会生成一个更复杂的正则表达式,例如'/(?i-mx:foo)|(?i-mx:bar)|(?i-mx:baz)/' 。 –

+0

@ muistooshort好的另一种选择是'Regexp.new(Regexp.union(PROJECTS).source,Regexp :: IGNORECASE)',这是目前为止我认为最好的选择。改变了我的答案。 –