Rodrigo Gurgel
Rodrigo Gurgel

Reputation: 1736

Trouble filling sub-matches using C++11's std::regex

I want to collect the Google Geolocation API's response:

{
  "location": {
   "lat": 37.42659,
   "lng": -122.07266190000001
  },
  "accuracy": 658.0
 }

I'm having difficulties to fill the sub-matches using std::regex:

  #include <string>
  #include <iostream>
  #include <regex>

  int main()
  {
     std::string json  = "{ \"location\": { \"lat\": 37.42659, \"lng\": -122.07266190000001 }, \"accuracy\": 658.0 }";
     std::string error = "error";

     if( json.find( "location" ) == std::string::npos ){
        std::cout << "ERROR" << std::endl;
     }

     if( error.find( "location" ) == std::string::npos ){
        std::cout << "ERROR" << std::endl;
     }

     try
     {
        std::regex pieces_regex("{ \"location\": { \"(lat)\": *([0-9.-]*),.*(lng)\": *([0-9.-]*).*(accuracy)\": *([0-9.-]*).*");
        std::smatch pieces_match;

        if (std::regex_match(json, pieces_match, pieces_regex)) {
           std::cout << json << '\n' << std::endl;
           for (size_t i = 0; i < pieces_match.size(); ++i) {
              std::ssub_match sub_match = pieces_match[i];
              std::string piece = sub_match.str();
              std::cout << "  submatch " << i << ": " << piece << '\n';
           }
        }
     }
     catch( std::regex_error &e )
     {
        std::cout << "ERRor: " << e.what() << std::endl;
     }

     return 0;

  }

Obs.: in g++ compile with --std=c++11 or higher

Using VIM's regex I can fit all sub-matches like a charm:

/{ "location": { "\(lat\)": *\([0-9.-]*\),.*\(lng\)": *\([0-9.-]*\).*\(accuracy\)": *\([0-9.-]*\).*

And works fine!

using above pattern on a :substitute command:

.s/{ "location": { "\(lat\)": *\([0-9.-]*\),.*\(lng\)": *\([0-9.-]*\).*\(accuracy\)": *\([0-9.-]*\).*/\1:\2 \3:\4 \5:\6/g

Upvotes: 0

Views: 111

Answers (1)

michalsrb
michalsrb

Reputation: 4891

As already commented parsing JSON with regex is not the best idea. Nevertheless, a working regular expression looks like this:

std::regex pieces_regex("\\{ \"location\": \\{ \"(lat)\": *([0-9.-]*),.*\"(lng)\": *([0-9.-]*).*\"(accuracy)\": *([0-9.-]*).*");

Upvotes: 1

Related Questions