regex.cpp 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. // Copyright Vladimir Prus 2002-2004.
  2. // Distributed under the Boost Software License, Version 1.0.
  3. // (See accompanying file LICENSE_1_0.txt
  4. // or copy at http://www.boost.org/LICENSE_1_0.txt)
  5. // This example shows how a user-defined class can be parsed using
  6. // specific mechanism -- not the iostream operations used by default.
  7. //
  8. // A new class 'magic_number' is defined and the 'validate' method is overloaded
  9. // to validate the values of that class using Boost.Regex.
  10. // To test, run
  11. //
  12. // regex -m 123-456
  13. // regex -m 123-4567
  14. //
  15. // The first invocation should output:
  16. //
  17. // The magic is "456"
  18. //
  19. // and the second invocation should issue an error message.
  20. #include <boost/program_options.hpp>
  21. #include <boost/regex.hpp>
  22. using namespace boost;
  23. using namespace boost::program_options;
  24. #include <iostream>
  25. using namespace std;
  26. /* Define a completely non-sensical class. */
  27. struct magic_number {
  28. public:
  29. magic_number(int n) : n(n) {}
  30. int n;
  31. };
  32. /* Overload the 'validate' function for the user-defined class.
  33. It makes sure that value is of form XXX-XXX
  34. where X are digits and converts the second group to an integer.
  35. This has no practical meaning, meant only to show how
  36. regex can be used to validate values.
  37. */
  38. void validate(boost::any& v,
  39. const std::vector<std::string>& values,
  40. magic_number*, int)
  41. {
  42. static regex r("\\d\\d\\d-(\\d\\d\\d)");
  43. using namespace boost::program_options;
  44. // Make sure no previous assignment to 'a' was made.
  45. validators::check_first_occurrence(v);
  46. // Extract the first string from 'values'. If there is more than
  47. // one string, it's an error, and exception will be thrown.
  48. const string& s = validators::get_single_string(values);
  49. // Do regex match and convert the interesting part to
  50. // int.
  51. smatch match;
  52. if (regex_match(s, match, r)) {
  53. v = any(magic_number(lexical_cast<int>(match[1])));
  54. } else {
  55. throw validation_error(validation_error::invalid_option_value);
  56. }
  57. }
  58. int main(int ac, char* av[])
  59. {
  60. try {
  61. options_description desc("Allowed options");
  62. desc.add_options()
  63. ("help", "produce a help screen")
  64. ("version,v", "print the version number")
  65. ("magic,m", value<magic_number>(),
  66. "magic value (in NNN-NNN format)")
  67. ;
  68. variables_map vm;
  69. store(parse_command_line(ac, av, desc), vm);
  70. if (vm.count("help")) {
  71. cout << "Usage: regex [options]\n";
  72. cout << desc;
  73. return 0;
  74. }
  75. if (vm.count("version")) {
  76. cout << "Version 1.\n";
  77. return 0;
  78. }
  79. if (vm.count("magic")) {
  80. cout << "The magic is \""
  81. << vm["magic"].as<magic_number>().n << "\"\n";
  82. }
  83. }
  84. catch(std::exception& e)
  85. {
  86. cout << e.what() << "\n";
  87. }
  88. }