Skip to content

Instantly share code, notes, and snippets.

@AntonioCS
Created August 21, 2019 16:21
Show Gist options
  • Save AntonioCS/44f8a52eca6ceebef60a26fb7f3e7a74 to your computer and use it in GitHub Desktop.
Save AntonioCS/44f8a52eca6ceebef60a26fb7f3e7a74 to your computer and use it in GitHub Desktop.
Using regex in C++ to transform a string into JSON
/**
This should transform the string:
- name=Maria, grades-90,age/25?university-UCL,surname=Hill,grades//85,graduates=5%ID=356231, graduates-7,grades=78//graduates=3
Into:
{
"output":{
"university":"UCL",
"students":{
"name":"Maria",
"surname":"Hill",
"age":25,
"ID":356231,
"grades":[
90,
85,
78
]
},
"graduates":15
}
}
clag flags: -O3 -std=c++2a -DFMT_HEADER_ONLY=1
CE: https://godbolt.org/z/DSElLr
*/
#include <iostream>
#include <regex>
#include <string> // std::string, std::stoi
#include <vector>
#include <optional>
#include <cstdio>
#include <fmt/format.h>
std::string formattedOutput(const std::string &input) {
auto getData = [&input](std::string str) -> std::optional<std::string> {
try {
std::regex reg{str + ".+?(\\w+)"};
std::smatch sm;
if (std::regex_search(input, sm, reg)) {
return { sm[1] };
}
} catch (const std::regex_error& e) {
std::cout << "regex_error caught: " << e.what() << '\n';
}
return {};
};
auto getGrades = [&input]() {
std::string localInput{input};
std::string grades{};
std::regex r(R"(grades.+?(\w+))");
std::smatch sm;
while(regex_search(localInput, sm, r)) {
if (!grades.empty()) {
grades += ", ";
}
grades += sm[1];
localInput = sm.suffix();
}
return grades;
};
//@Todo: move this and the above function to one
auto getGraduatesTotal = [&input]() {
std::string localInput{input};
int total{};
std::regex r(R"(graduates.+?(\w+))");
std::smatch sm;
while(regex_search(localInput, sm, r)) {
total += std::stoi(sm[1]);
localInput = sm.suffix();
}
return total;
};
std::string output = R"({{)"
R"( "output":{{)"
R"( "university":"{}",)"
R"( "students":{{)"
R"( "name":"{}",)"
R"( "surname":"{}",)"
R"( "age":{},)"
R"( "ID":{},)"
R"( "grades":[{}])"
R"( }},)"
R"( "graduates":{})"
R"( }})"
R"(}})";
return fmt::format(output,
*getData("university"),
*getData("name"),
*getData("surname"),
*getData("age"),
*getData("ID"),
getGrades(),
getGraduatesTotal()
);
}
int main()
{
const std::string input{R"(name=Maria, grades-90,age/25?university-UCL,surname=Hill,grades//85,graduates=5%ID=356231, graduates-7,grades=78//graduates=3)"};
std::cout << formattedOutput(input) << '\n';
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment