Hemant Bhargava
Hemant Bhargava

Reputation: 3585

Parsing the string and populate the map

Consider this:

command1 -keep -path { {path1} }  { {./input.doc} }

I wanted to parse the above line and collect the information into a map where value would be contents of -path option and key would be everything else. The format of the string would be fixed that after -path there would be two opening and two closes brackets. In this case,

key would be:

command1 -keep { {./input.doc} }

Value would be:

path1

I was doing it using brute force method as like:

Get the position of -path.

Get the position of second closing bracket.

Little more processing and create two substring of -path and remaining else with above two positions. Like this:

#include<iostream>
#include<cstring>

int main() {
  std::string s1 = "command1 -keep -path { {path1} }  { {./input.doc} }";

  std::size_t found = s1.find("-path");
  std::size_t closeBracesPos = s1.find_first_of("}",s1.find_first_of("}")+1);
  std::string preS1                  = s1.substr(0, found);
  std::string postS1                 = s1.substr(closeBracesPos+1);
  std::string pathStr                = s1.substr(found+1, s1.size() - preS1.size() - postS1.size());

  std::size_t pathStrOpeningBracePos = pathStr.find_last_of("{");
  std::size_t pathStrClosingBracePos = pathStr.find_first_of("}");
  std::string pathStrOpeningBrace = pathStr.substr(0, pathStrOpeningBracePos);
  std::string pathStrClosingBrace = pathStr.substr(pathStrClosingBracePos);
  std::string pathNames           = pathStr.substr(pathStrOpeningBracePos+1, pathStr.size()-pathStrOpeningBrace.size()-pathStrClosingBrace.size()-1);

  std::string remainingStr = preS1 + " " + postS1;
  std::cout << "PATH NAMES :" << pathNames << std::endl;
  std::cout << "Remaining :" << remainingStr << std::endl;
}      

This seems little rusty to me. Can we discuss other methods to extract this information?

Upvotes: 0

Views: 85

Answers (1)

Jarod42
Jarod42

Reputation: 217478

With regex, you might do:

std::string s1 = "command1 -keep -path { {path1} }  { {./input.doc} }";
std::regex pattern{R"((.*)-path \{ \{([^}]*)\} \}(.*))"};

std::smatch obj;
if (std::regex_match(s1, obj, pattern))
{
    std::string key = obj[1].str() + obj[3].str();
    std::string value = obj[2].str();

    // ...
}

Demo

Upvotes: 2

Related Questions