【问题标题】:Unable to find matches using Boost RegEx无法使用 Boost RegEx 找到匹配项
【发布时间】:2019-02-10 09:46:56
【问题描述】:

我正在使用 boost 1.67.0 regex 使用以下 sn-p 在当前文件夹中查找匹配的文件名

boost::filesystem::path p(".");
if(is_directory(p)) {

    for(auto& entry : boost::make_iterator_range(boost::filesystem::directory_iterator(p), {})){
        std::stringstream ss;
        ss << entry;
        std::string filename = ss.str();
        std::cout << filename << std::endl;
        boost::regex pattern("some_\\d+_file\.txt");

        if(boost::regex_match(filename, pattern)){
            std::cout << "matched" << filename << std::endl;
        }            
    }   
}

std::cout &lt;&lt; filename &lt;&lt; std::endl; 行产生的当前目录的内容是:

"./myApp.out"
"./some_0_file.txt"
"./some_1_file.txt"
"./other_file.txt"
"./some_other_file.txt"
"./some_2_file.txt"

为了确认我的匹配表达式是正确的,我咨询了Perl Regular Expression Syntax。也使用RegEx101.com确认,输出正确显示3个匹配如下:

some_0_file.txt
some_1_file.txt
some_2.file.txt

问题

我的 sn-p 或 RegEx 有什么问题吗?为什么boost::regex_match 产生 0 匹配?

我错过了什么?

【问题讨论】:

    标签: c++ regex c++11 boost boost-regex


    【解决方案1】:
    boost::filesystem::path p(".");
    if (is_directory(p)) {
    
        for (auto& entry : boost::make_iterator_range(boost::filesystem::directory_iterator(p), {})) {
            std::stringstream ss;
            ss << entry.path().string(); //2
            std::string filename = ss.str();
            std::cout << filename << std::endl;
            boost::regex pattern(".*some_\\d+_file\\.txt"); //1
            if (boost::regex_match(filename, pattern)) {
                std::cout << "matched" << filename << std::endl;
            }
        }
    }
    

    1.regex_match 只考虑完全匹配

    2.operator&lt;&lt;(std::basic_ostream&lt;Char, Traits&gt;&amp; os, const path&amp; p) 将使用boost::io::quoted() 并添加引号来处理路径中的空格

    【讨论】:

    • 这解决了我的问题,谢谢。与@Ptaq66 的答案唯一不同的是ss &lt;&lt; entry.path().string(); 行。
    • 一开始就没有理由打扰流。此外,将正则表达式排除在循环之外。最后,不需要迭代器范围(是的,那是 surprising) 非常简化的演示:coliru.stacked-crooked.com/a/ca553af0515f16f3
    【解决方案2】:

    因为regex_match 只考虑完全匹配。这意味着,您需要在您的模式中包含./。你也错误地转义了最后一个点。你的模式应该是:

    boost::regex pattern("\\./some_\\d+_file\\.txt");
    

    (或者你可以使用.*作为文件路径的开头,只是不要硬编码./

    或者,您可以使用regex_search,如果部分字符串与表达式匹配,则返回 TRUE。

    【讨论】:

    • 感谢您的回答。我尝试了"\\./some_\\d+_file\\.txt""\\.*some_\\d+_file\\.txt" 作为我的模式。不幸的是,他们都没有工作。仍然得到0匹配。我要试试regex_search
    • 是的,正如@user338371 所提到的,您的文件名中还包含引号,在查找完整匹配项时必须考虑到这一点。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-12-09
    • 1970-01-01
    • 2011-11-10
    • 2011-08-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多