Konrad
Konrad

Reputation: 18595

Replacing lines via boost regex with boost for relatively complex regex

Background

I'm looking to replace replace all lines from a file that start with -- or with [[:space:]]{1,}. Broadly speaking, I'm looking to achieve the results that would be similar to this answer.

Code

/*
 * so_question.cpp
 * Read text files and remove all lines starting with -- or <space>*--
 * Clean text is passed to cout.
 * 
 * Compile and test:
 * clang++ -lboost_regex -Wall -std=c++11 so_question.cpp -o so_question && ./so_question tst.sql
 */


#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <boost/regex.hpp>
#include <boost/algorithm/string/replace.hpp>

int main(int argc, char *argv[]) {

    // Read file to stringstream
    std::ifstream file( argv[1] );

    if ( file )
    {
        std::stringstream buffer;

        buffer << file.rdbuf();

        file.close();

        // Create a string variable to apply boost::regex
        std::string readText;
        readText = buffer.str();

        // Regular expression finding comments
        boost::regex re_comment("^([[:space:]]{1,}|)--.*(\n|\r|)$");

        // Replace desired lines
        // boost::replace_all(readText, re_comment, " ");

        // Replace via regex replace
        std::string result = boost::regex_replace(readText, re_comment, " ");

       // Show clean text when using regex_replace
       std::cout << "\nClean text:\n" << result << std::endl;

        // Show clean text
        // std::cout << "Clean text:" << readText << std::endl;


        return 0;
    }

}

Test data

-- Query taken from:
-- https://stackoverflow.com/a/12467388/1655567
SELECT country.name as country, country.headofstate
from country
    -- Worst place to add comment ever
  -- Here is even uglier
inner join city on city.id = country.capital
where city.population > 100000
-- this comment makes no sense here and would break sql parser buyt hey
and country.headofstate like 'A%'
-- WOW!

Desired results

SELECT country.name as country, country.headofstate
from country
inner join city on city.id = country.capital
where city.population > 100000
and country.headofstate like 'A%'

Compilation and test

clang++ -lboost_regex -Wall -std=c++11 so_question.cpp -o so_question && ./so_question tst.sql

Problem

The returned text is exactly the same as in the provided file. I reckon that the problem is with the particular regex syntax I'm using. However, after reading boost regex documentation and testing multiple versions of that regex it's not clear to me what the right syntax should be.

Upvotes: 2

Views: 460

Answers (2)

Jan
Jan

Reputation: 43169

Rearrange your parentheses:

(?m)^(?:--|[[:space:]]+).+

And see a demo on regex101.com. Note that [[:space:]]{1,} is the same as [[:space:]]+.

Upvotes: 1

SoronelHaetir
SoronelHaetir

Reputation: 15172

The form of regex_replace that you call returns the string with replacements, it does not operate in-place.

Upvotes: 0

Related Questions