I'd like to parse a string like "{{0, 1}, {2, 3}}" into a std::map. I can write a small function for parsing a string using <regex> library, but I have no idea how to check whether a given string is in a valid format. How can I validate the format of a string?
#include <list>
#include <map>
#include <regex>
#include <iostream>
void f(const std::string& s) {
std::map<int, int> m;
std::regex p {"[\\[\\{\\(](\\d+),\\s*(\\d+)[\\)\\}\\]]"};
auto begin = std::sregex_iterator(s.begin(), s.end(), p);
auto end = std::sregex_iterator();
for (auto x = begin; x != end; ++x) {
std::cout << x->str() << '\n';
m[std::stoi(x->str(1))] = std::stoi(x->str(2));
}
std::cout << m.size() << '\n';
}
int main() {
std::list<std::string> l {
"{{0, 1}, (2, 3)}",
"{{4, 5, {6, 7}}" // Ill-formed, so need to throw an excpetion.
};
for (auto x : l) {
f(x);
}
}
NOTE: I don't feel obliged to use regex to solve this problem. Any kind of solutions, including some ways validating and inserting at once by subtracting substrings, will be appreciated.
In my opinion, Spirit-based parser is always much more robust and readable. It is also much more fun to parse with Spirit :-). So, in addition to @Aleph0 's answer, I'd like to provide a compact solution based on Spirit-X3:
#include <string>
#include <map>
#include <iostream>
#include <boost/fusion/adapted/std_pair.hpp>
#include <boost/spirit/home/x3.hpp>
int main() {
std::string input ="{{0, 1}, {2, 3}}";
using namespace boost::spirit::x3;
const auto pair = '{' > int_ > ',' > int_ > '}';
const auto pairs = '{' > (pair % ',') > '}';
std::map<int, int> output;
// ignore spaces, tabs, newlines
phrase_parse(input.begin(), input.end(), pairs, space, output);
for (const auto [key, value] : output) {
std::cout << key << ":" << value << std::endl;
}
}
Note that I used operator >, which means "expect". So, if the input does not match the expectation, Spirit throws an exception. If you prefer a silent failure, use operator >> instead.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With