使用Boost Regex替换注释行失败,求正则修正及LLVM头文件排序规范
解决你的两个问题:正则匹配失效与LLVM头文件排序规范
一、正则表达式匹配失效的问题
你的核心问题是未启用多行模式,导致^和$仅匹配整个字符串的首尾,而非每行的开头和结尾。另外正则表达式可以优化,替换逻辑也需要调整才能得到预期结果。
修正后的关键调整
- 启用多行模式:创建
boost::regex时添加boost::regex::multiline标志,让^匹配每行开头、$匹配每行结尾,这样才能识别所有符合条件的注释行。 - 优化正则表达式:原需求是匹配“行首直接--”或“行首带空格后接--”,可以简化为
^[[:space:]]*--.*$([[:space:]]*包含0个或多个空格,刚好覆盖两种场景;如果严格要求“至少一个空格”的情况,可写成^(?:--|[[:space:]]+--).*$)。 - 替换为空字符串:你原来替换成空格会留下空行,改成替换为
""就能彻底删除目标行。
修正后的核心代码片段:
// 启用多行模式的正则表达式 boost::regex re_comment("^[[:space:]]*--.*$", boost::regex::multiline); // 替换为空字符串,彻底删除匹配的行 std::string result = boost::regex_replace(readText, re_comment, "");
原正则失效的原因
默认情况下,boost::regex的^和$仅匹配整个输入字符串的首尾,所以你的正则只会匹配文件第一行或最后一行是注释的情况,无法识别中间的注释行。添加multiline标志后,才能正确匹配每行的注释。
二、LLVM风格的头文件排序规范
根据LLVM编码指南,头文件需按以下顺序排列,每组内按字典序排序,组间用空行分隔:
- 当前源文件对应的头文件:如果cpp文件有匹配的.h文件(比如
so_question.cpp对应so_question.h),放在最开头。 - C标准库头文件:比如
<stdio.h>、<stdlib.h>这类C语言原生头文件。 - C++标准库头文件:比如
<iostream>、<fstream>这类C++标准库头文件。 - 第三方库头文件:比如Boost的
<boost/regex.hpp>这类第三方依赖头文件。 - 项目内部头文件:你自己项目中的其他自定义头文件。
针对你的代码的正确排序
你的代码头文件调整后应该是:
#include <iostream> #include <fstream> #include <sstream> #include <string> #include <boost/algorithm/string/replace.hpp> #include <boost/regex.hpp>
完整修正后的代码
/* * 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/algorithm/string/replace.hpp> #include <boost/regex.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 = buffer.str(); // Regular expression finding comments - enable multiline mode boost::regex re_comment("^[[:space:]]*--.*$", boost::regex::multiline); // Replace desired lines with empty string to remove them std::string result = boost::regex_replace(readText, re_comment, ""); // Show clean text std::cout << "\nClean text:\n" << result << std::endl; return 0; } // Handle file open failure std::cerr << "Failed to open file: " << argv[1] << std::endl; return 1; }
编译测试
使用你原来的命令即可:
clang++ -lboost_regex -Wall -std=c++11 so_question.cpp -o so_question && ./so_question tst.sql
运行后就能得到你期望的结果,所有符合条件的注释行都会被彻底删除。
内容的提问来源于stack exchange,提问作者Konrad
相关产品推荐
相关产品推荐

