【问题标题】:Replacing lines via boost regex with boost for relatively complex regex通过 boost regex 用 boost 替换行,以获得相对复杂的 regex
【发布时间】:2018-06-22 14:41:23
【问题描述】:

背景

我希望替换文件中以 --[[:space:]]{1,} 开头的所有行。从广义上讲,我希望获得类似于this answer 的结果。

代码

/*
 * 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;
    }

}

测试数据

-- 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!

期望的结果

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%'

编译测试

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

问题

返回的文本与提供的文件中的完全相同。我认为问题出在我正在使用的特定正则表达式语法上。但是,在阅读了 boost regex documentation 并测试了该正则表达式的 multiple versions 之后,我不清楚正确的语法应该是什么。

  • ALE 指出 #includes 没有正确排序。考虑到llvm guidelines 正确的顺序是什么(这是支点,与主要问题无关)

【问题讨论】:

  • 您能否检查一下您是否放错了| 交替符号?我的第一个猜测是你做到了,它应该在捕获组之外,即在 ) 之后
  • @Rahul 感谢您的评论。我会看一下,实际上我正在寻找 (\n|\r|\z) 行上的东西,所以所有换行符和字符串结束。我认为\z 在 boost 中不起作用,但我会研究 |
  • 要检查以-- 开头的行,您不必检查以.*(\n|\r|)$ 开头的行的其余部分。只有^-- 就足够了。
  • @Rahul 公平点,我还想在-- 之前捕获任何空格,[[:space:]]*-- 可以吗?
  • 你正在编译 c++11。为什么不使用std::regex

标签: c++ regex string boost


【解决方案1】:

你调用的 regex_replace 形式返回带有替换的字符串,它不会就地操作。

【讨论】:

  • 我已将boost::regex_replace 更改为:std::string result = boost::regex_replace(readText, re_comment, " ");
【解决方案2】:

重新排列括号:

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

还有see a demo on regex101.com。请注意[[:space:]]{1,}[[:space:]]+ 相同。

【讨论】:

  • 我已经尝试了语法:boost::regex re_comment("(?m)^(?:--|[[:space:]]+).+"); 并得到了结果:`std::string result = boost::regex_replace(readText, re_comment, " ");` 但我继续得到运行时空行:std::cout &lt;&lt; "\nClean text:\n" &lt;&lt; result &lt;&lt; std::endl;
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-05-05
  • 2011-08-12
  • 1970-01-01
  • 1970-01-01
  • 2012-11-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多