假设我想匹配以下管道分隔的字符串:
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()代替?)。
答案 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);
(您可以使用sed
或grep
代替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;
}