2011-10-26 32 views
0
通配符管道分隔字符串

想我想匹配以下管道分隔字符串:C++:匹配與使用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 ::實現does_match()的最佳方式正則表達式?

我想我可能會遇到轉義管道和星星的問題。請注意,我不關心實際匹配:我只是想要一個易於使用的界面來0123?告訴我,如果我有一場比賽。

特別是,我希望能夠在不必爲管道和星星使用大量逃逸的情況下工作。我不關心正則表達式的其他更普遍的用法 - 如果我可以使用管道分隔符和*作爲通配符,那就足夠了。

也許我應該在does_match中做一個轉換以使boost :: regex高興?或者,也許我的整個方法是不好的(就像我應該使用某種strsplit())?)。

+1

好,'|'*是*特殊字符在任何形式的正則表達式語言,這樣你就不會得到解決逃了......你要知道,C++字符串字面量也需要轉義反斜槓,因此它'會像'「a \\\ | * \\\ | c」'。希望沒有,就像「我希望編寫一些沒有所有大括號和類的C++」。 –

+1

@KerrekSB:一個額外\就夠了,星星不能孤單(這是一個修飾符)。所以正則表達式的C++字符串將是''a \\ |。* \\ | c「'。 –

+0

@JoachimPileborg:謝謝,我的錯誤,的確如此! –

回答

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; 
} 
1

我認爲你的正則表達式必須是這樣a\\|.*?\\|c才能匹配你想要的。 |有特殊含義(邏輯或)。並且*具有特殊含義(零次或多次)。如果中間部分是強制性的,則使用a\\|.+?\\|c

1

您正在嘗試執行的默認模式需要 "a\\|.*\\|c"。如果您的編譯器支持C++ 11,則可以使用原始的 字符串來指定: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); 

(你可以使用sedgrepbasic代替。)