C ++:使用boost :: regex匹配管道分隔的字符串和通配符

时间:2011-10-26 11:34:42

标签: c++ regex boost

假设我想匹配以下管道分隔的字符串:

std::string re("a|*|c");
std::string x("a|b|c");
std::string y("a|c|d");

does_match( re, x );  // want to return TRUE
does_match( re, y );  // want to return FALSE

使用boost :: regex实现does_match()的最佳方法是什么?

我想我可能会遇到逃避管道和星星的问题。请注意,我不关心实际的匹配:我只想要一个易于使用的does_match()界面告诉我是否有匹配。

特别是,我希望无需使用大量的管道和星星逃生即可实现这一目标。我不关心正则表达式的其他更普遍的用法 - 如果我可以使用管道分隔符和*用于通配符,那就足够了。

也许我应该在do_match中进行转换以使boost :: regex快乐?或许我的整个方法都很糟糕(比如我应该使用某种strsplit()代替?)。

3 个答案:

答案 0 :(得分:1)

我认为你的正则表达式必须像a\\|.*?\\|c这样才能匹配你想要的东西。 |具有特殊含义(逻辑或)。并且*具有特殊含义(零次或多次)。如果中间部分是必填部分,则使用a\\|.+?\\|c

答案 1 :(得分:1)

您尝试执行的操作的默认模式需要 "a\\|.*\\|c"。如果你的编译器支持C ++ 11,你可以使用raw 字符串来指定:R"(a\|.*\|c)". Otherwise, you can use a syntax in which | was not a meta-character; Boost supports the Posix basic syntax, for example, which doesn't support the or-operator, so you could write“a |。* | c”`:

boost::regex pattern("a|.*|c", boost::regex::basic);

(您可以使用sedgrep代替basic。)

答案 2 :(得分:0)

好吧,我想我试图用boost :: regex()来解决这个错误的树 - boost :: split()可能更合适。

#include <string>
#include <vector>

#include <boost/algorithm/string.hpp>

bool does_match( const std::string& fmt, const std::string& str )
{
    std::vector<std::string> strs, fmts;
    boost::split( strs, str, boost::is_any_of( "|" ));
    boost::split( fmts, fmt, boost::is_any_of( "|" ));
    if ( strs.size()!=fmts.size() )
        return false;
    size_t n = strs.size(); 
    for( size_t i=0; i<n; ++i )
        if ( fmts[i].compare("*")  && fmts[i].compare( strs[i] ))
            return false;
    return true;
}