Parsing Boost regex与多个regex网站不匹配
我试图使用正则表达式解析字符串,这样当我迭代它的匹配项时,它只会给出结果。我的目标是找到所有Parsing Boost regex与多个regex网站不匹配,parsing,c++11,boost,comments,boost-regex,Parsing,C++11,Boost,Comments,Boost Regex,我试图使用正则表达式解析字符串,这样当我迭代它的匹配项时,它只会给出结果。我的目标是找到所有 #include <stuff.h> #include "stuff.h" 这里是我的函数,用于读取一个文件,将其转换为字符串,并解析字符串,创建标记,然后对这些标记进行迭代以打印它们。 tokes将包含基于前面几行的stuff.h,stuff.h 我遇到的问题是使用这个正则表达式 问题是,我的正则表达式是错的还是函数中有什么东西 void header_check::filename(c
#include <stuff.h>
#include "stuff.h"
这里是我的函数,用于读取一个文件,将其转换为字符串,并解析字符串,创建标记,然后对这些标记进行迭代以打印它们。
tokes将包含基于前面几行的stuff.h
,stuff.h
我遇到的问题是使用这个正则表达式
问题是,我的正则表达式是错的还是函数中有什么东西
void header_check::filename(const boost::filesystem::directory_iterator& itr) //function takes directory path
{
std::string delimeter ("#include.+(?:<|\\\")(.+)(?:>|\\\")(?![^*\\/]* (?:\\*+(?!\\/)[^*\\/]*|\\/+(?!\\*)[^*\\/]*)*\\*\\/)");//regex storage
boost::regex regx(delimeter,boost::regex::perl);//set up regex
boost::smatch match;
std::ifstream file (itr->path().string().c_str());//stream to transfer to stream
std::string content((std::istreambuf_iterator<char>(file)),
std::istreambuf_iterator<char>());//string to be parsed
boost::sregex_token_iterator iter (content.begin(),content.end(), regx, 0); //creates a match for each search
boost::sregex_token_iterator end;
for (int attempt =1; iter != end; ++iter) {
std::cout<< *iter<<" include #"<<attempt++<<"\n"; //prints results
}
}
void header\u check::filename(const boost::filesystem::directory\u iterator&itr)//函数采用目录路径
{
string delimeter(“#include.+(?:首先,您在正则表达式中有一个额外的空格字符
但真正的问题是,您将整个输入视为一行。如果设置该标志:
你会发现的
在正则表达式中,默认情况下,所有开放的量词都是贪婪的。因此,必须更加具体
#include.+
这已经结束了,因为+
只是匹配所有内容(直到并包括最后一行)。您唯一的缓刑是将发生回溯,以便至少有一个正则表达式的“尾”匹配,但所有其余的都“增强”“介于两者之间。因为+
逐字要求1或尽可能多的任何字符”
尝试修复。。。
将+
设为\s+
左右。事实上,它必须是\s*
,因为#include
完全有效++
接下来,您不能像以前那样匹配,因为您很乐意匹配#include
。而且,*
需要限制。在这种情况下,您可以使结束分隔符完全确定(因为开始分隔符完全预测它),因此您可以使用非贪婪的Kleene星形:
#include\s*("(.*?)"|<(.*?)>)
哇。这是一股新鲜空气。这几乎就像编程,而不是巫术和交叉拇指
现在来看看真正的肉:
auto include_ = "#include" >> (
'<' >> *~char_('>') >> '>'
| '"' >> *~char_('"') >> '"'
);
扩大到所有未评论的内容会是小菜一碟吗
std::vector<std::string> headers;
bool ok = phrase_parse(content.begin(), content.end(), *seek[include_], comment_, headers);
它确实有点失去了优雅,但它确实起作用:
满月
完整演示
matched: true: iostream
// #include <boost/graph/adjacency_list.hpp>
#include "iostream"
#include<fstream> /*
#include <boost/filesystem.hpp>
#include <boost/regex.hpp> */ //
#include <boost/spirit/home/x3.hpp>
void filename(std::string const& fname) //function takes directory path
{
using namespace boost::spirit::x3;
auto comment_ = space
| "//" >> *(char_ - eol)
| "/*" >> *(char_ - "*/")
;
auto name_ = rule<struct _, std::string> {} = lexeme[
'<' >> *(char_ - '>' - eol) >> '>'
| '"' >> *(char_ - '"' - eol) >> '"'
];
auto include_ = "#include" >> name_;
auto const content = [&]() -> std::string {
std::ifstream file(fname);
return { std::istreambuf_iterator<char>{file}, {} };//string to be parsed
}();
std::vector<std::string> headers;
/*bool ok = */phrase_parse(content.begin(), content.end(), *(omit[*(char_ - include_)] >> include_) , comment_, headers);
std::cout << "matched: " << headers.size() << " active includes:\n";
for (auto& header : headers)
std::cout << " - " << header << "\n";
}
int main() {
filename("main.cpp");
}
而不是Perl6,在这种情况下你可以被原谅
²我明天会尝试修复/报告此问题我注意到您已标记。以下是对的琐碎修改。(讽刺的是,repository::qi::seek[]
)。非常感谢您。我尖叫是因为我还无法对您的答案进行投票。慢慢来,一旦您发现它是否解决了您的问题,您总是可以接受的(另请参阅)
matched: true: iostream
std::vector<std::string> headers;
bool ok = phrase_parse(content.begin(), content.end(), *seek[include_], comment_, headers);
auto name_ = rule<struct _, std::string> {} = lexeme[
'<' >> *(char_ - '>' - eol) >> '>'
| '"' >> *(char_ - '"' - eol) >> '"'
];
auto include_ = "#include" >> name_;
bool ok = phrase_parse(content.begin(), content.end(), *(omit[*(char_ - include_)] >> include_) , comment_, headers);
// #include <boost/graph/adjacency_list.hpp>
#include "iostream"
#include<fstream> /*
#include <boost/filesystem.hpp>
#include <boost/regex.hpp> */ //
#include <boost/spirit/home/x3.hpp>
void filename(std::string const& fname) //function takes directory path
{
using namespace boost::spirit::x3;
auto comment_ = space
| "//" >> *(char_ - eol)
| "/*" >> *(char_ - "*/")
;
auto name_ = rule<struct _, std::string> {} = lexeme[
'<' >> *(char_ - '>' - eol) >> '>'
| '"' >> *(char_ - '"' - eol) >> '"'
];
auto include_ = "#include" >> name_;
auto const content = [&]() -> std::string {
std::ifstream file(fname);
return { std::istreambuf_iterator<char>{file}, {} };//string to be parsed
}();
std::vector<std::string> headers;
/*bool ok = */phrase_parse(content.begin(), content.end(), *(omit[*(char_ - include_)] >> include_) , comment_, headers);
std::cout << "matched: " << headers.size() << " active includes:\n";
for (auto& header : headers)
std::cout << " - " << header << "\n";
}
int main() {
filename("main.cpp");
}
matched: 3 active includes:
- iostream
- fstream
- boost/spirit/home/x3.hpp