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