2016-09-27 144 views
1

有没有办法有像升压program_options自定义分析

myapp hostname:port 

通过升压program_options解析?我也使用其他选项,我很乐意使用boost program_options,而无需为argc/argv推出我自己的解析器。

我试着用的

desc.add_options() 
    ("help", "list all available options") 
    (new MyCustomValue(&store_var), "") 

一些组合,但由于丹马塞克写道:它没有工作

+0

[文档]( http://www.boost.org/doc/libs/1_61_0/doc/html/program_options/howto.html#idp308985408)自定义验证器应该对此有所了解。 –

+0

@DanMašek它不是一个简单的理由:它也需要在一个完整或缩短的选项前缀,例如, 'myapp -a hostname:port',而我只想在它之前输入像ssh:'myapp hostname:port'这样的没有'-something'的东西。 – Dean

+0

[位置选项](http://www.boost.org/doc/libs/1_61_0/doc/html/program_options/overview.html#idp308857536)会这样做。 –

回答

0

,这看起来对于一个位置参数更合适。既然您为该选项指定了特定结构,但您可能需要添加std::regex_match

假设您从

#include <string> 
#include <iostream> 
#include <regex> 
#include <boost/program_options.hpp> 

using namespace std; 
using namespace boost::program_options; 

int main(int argc, const char *argv[]) { 
    try { 
     options_description desc{"Options"}; 
     desc.add_options() 
      ("help,h", "Help screen") 
      ("ip_port", value<std::string>()->required(), "ip:port"); 

     positional_options_description pos_desc; 
     pos_desc.add("ip_port", -1); 

     command_line_parser parser{argc, argv}; 
     parser.options(desc).positional(pos_desc).allow_unregistered(); 
     parsed_options parsed_options = parser.run(); 

     variables_map vm; 
     store(parsed_options, vm); 
     notify(vm); 

     const auto ip_port = vm["ip_port"].as<string>(); 

在这一点上,我们有用户对ip_port输入。我们可以定义一个正则表达式来匹配它。请注意,第一部分可以是一个字符串(例如,localhost),但第二部分必须是一个整数:

 const regex ip_port_re("([^:]+):([[:digit:]]+)"); 
     smatch ip_port_match; 
     if(!regex_match(ip_port, ip_port_match, ip_port_re)) 
      throw validation_error{validation_error::invalid_option_value, ip_port, "ip_port"}; 
     cout << "ip: " << ip_port_match[1] << " port: " << ip_port_match[2] << endl; 
    } 
    catch (const error &ex) { 
     cerr << ex.what() << '\n'; 
    } 
} 

当运行它,它看起来像这样:

$ g++ --std=c++11 po.cpp -lboost_program_options && ./a.out 127.0.0.1:30 
ip: 127.0.0.1 port: 30 
$ g++ --std=c++11 po.cpp -lboost_program_options && ./a.out localhost:30 
ip: localhost port: 30 
$ g++ --std=c++11 po.cpp -lboost_program_options && ./a.out localhost:30d 
the argument for option 'localhost:30d' is invalid 
$ g++ --std=c++11 po.cpp -lboost_program_options && ./a.out 
the option '--ip_port' is required but missing 
$ g++ --std=c++11 po.cpp -lboost_program_options && ./a.out localhost:30 foo 
option '--ip_port' cannot be specified more than once