我使用各种正则表达式来逐行解析C源文件。首先,我用字符串读取文件的所有内容:
ifstream file_stream("commented.cpp",ifstream::binary);
std::string txt((std::istreambuf_iterator<char>(file_stream)),
std::istreambuf_iterator<char>());
然后我使用一组正则表达式,应该连续应用,直到匹配找到,这里我只给出一个例如:
vector<regex> rules = { regex("^//[^\n]*$") };
char * search =(char*)txt.c_str();
int position = 0, length = 0;
for (int i = 0; i < rules.size(); i++) {
cmatch match;
if (regex_search(search + position, match, rules[i],regex_constants::match_not_bol | regex_constants::match_not_eol))
{
position += ( match.position() + match.length() );
}
}
但它不起作用。它将匹配不在当前行中的评论,但会搜索整个字符串,对于第一个匹配,regex_constants::match_not_bol
和regex_constants::match_not_eol
应使regex_search
识别^$
为仅开始/结束行,而不是整个块的结束开始/结束。所以这是我的文件:
commented.cpp:
#include <stdio.h>
//comment
代码应该失败,我的逻辑是使用regex_search的那些选项,匹配应该失败,因为它应该在第一行搜索模式:
#include <stdio.h>
但是它会搜索整个字符串,并且不可避免地找到//comment
。我需要帮助,只能在当前行中匹配regex_search
。选项match_not_bol
和match_not_eol
对我没有帮助。当然我可以在一个向量中逐行读取一个文件,然后匹配vector中每个字符串的所有规则,但它很慢,我已经这样做了,并且解析一个大文件需要很长时间那就是为什么我想让正则表达式处理新行,并使用定位计数器。
答案 0 :(得分:1)
如果不是您想要的,请发表评论,以便我删除答案
您正在做的不是使用正则表达式库的正确方法
因此,我建议任何想要使用std::regex
库的人。
ECMAScript
以某种方式
比所有现代regex
库都差。它有很多你喜欢的错误(只是我发现):
在某些情况下(我专门针对std::match_results
测试)与d语言中的std.regex
相比, 200 慢
flag-match
,几乎不起作用(至少对我而言)结论:根本不要使用它。
但如果有人仍然要求使用c++那么你可以:
使用boost::regex
about Boost library 因为:
PCRE
支持std::regex
使用下面的gcc version 7.1.0
和 NOT 。我发现的最后一个错误是版本6.3.0
clang version 3
或以上如果你诱使(=说服) NOT 使用c++,那么你可以使用:
答案 1 :(得分:0)
#include <stdio.h> //comment
代码应该失败,我的逻辑是使用regex_search的那些选项,匹配应该失败,因为它应该在第一行搜索模式:
#include <stdio.h>
但是它搜索整个字符串,并且不断发现//评论。我需要帮助,只能在当前行中使regex_search匹配。
您是要尝试匹配源代码文件中的所有//
个评论,还是只匹配第一行?
前者可以这样做:
#include <iostream>
#include <fstream>
#include <regex>
int main()
{
auto input = std::ifstream{"stream_union.h"};
for(auto line = std::string{}; getline(input, line); )
{
auto submatch = std::smatch{};
auto pattern = std::regex(R"(//)");
std::regex_search(line, submatch, pattern);
auto match = submatch.str(0);
if(match.empty()) continue;
std::cout << line << std::endl;
}
std::cout << std::endl;
return EXIT_SUCCESS;
}
后者可以这样做:
#include <iostream>
#include <fstream>
#include <regex>
int main()
{
auto input = std::ifstream{"stream_union.h"};
auto line = std::string{};
getline(input, line);
auto submatch = std::smatch{};
auto pattern = std::regex(R"(//)");
std::regex_search(line, submatch, pattern);
auto match = submatch.str(0);
if(match.empty()) { return EXIT_FAILURE; }
std::cout << line << std::endl;
return EXIT_SUCCESS;
}
如果出于任何原因你想要获得比赛的位置,tellg()会为你做到这一点。