生成正则表达式的所有可能匹配

时间:2015-03-04 18:41:47

标签: c++ string algorithm expansion string-interpolation

如何获得正则表达式的所有可能匹配

例如:

  

((A,B,C)O(M,V)P,B)

从上面的表达式生成的字符串将是:

  

aomp

     

BOMP

     

排版

     

aovp

     

bovp

     

COVP

     

B'/ P>

1 个答案:

答案 0 :(得分:4)

您的步骤非常简单,但实施它们可能需要一些工作:

  1. 创建一个递归函数,在第一组括号之间提取字符串:https://stackoverflow.com/a/28863720/2642059
  2. 在函数中将','上的这个字符串拆分为vector<string>并将其返回:https://stackoverflow.com/a/28880605/2642059
  3. 在返回测试之前,如果由于嵌套的括号需要递归,则必须为递归函数返回的每个可能组合的返回添加一个字符串
  4. 修改

    说我的输入字符串是&#34;(bl(啊,eck,le),yap)&#34;

    • 第一个函数将提取string:&#34; bl(啊,eck,le),yap&#34;
    • 在返回之前,它会搜索嵌套的括号,这会导致它递归:
      • 第二个函数将提取string:&#34;啊,eck,le&#34;
      • 在返回之前,它会搜索嵌套的括号并找不到
      • 它会返回vector<string>:[&#34;啊&#34;,&#34; eck&#34;,&#34; le&#34;]
    • 第一个功能现在包含:&#34; bl [&#34;啊&#34;,&#34; eck&#34;,&#34; le&#34;],yap&#34;
    • 它不会再找到提取的括号,所以它将扩展所有内部组合:&#34; [&#34; blah&#34;,&#34; bleck&#34;,&#34; blle& #34],邑&#34;
    • 它现在可以分割字符串并返回:[&#34; blah&#34;,&#34; bleck&#34;,&#34; blle&#34;,&#34; yap&#34;] < / LI>

    第一个功能的回报是你的结果。

    修改

    很高兴你解决了它我写了一个两个状态机来解决它所以我想我可以在这里发布你的比较:

    const char* extractParenthesis(const char* start, const char* finish){
        int count = 0;
    
        return find_if(start, finish, [&](char i){
            if (i == '('){
                count++;
            }
            else if (i == ')'){
                count--;
            }
            return count <= 0; });
    }
    
    vector<string> split(const char* start, const char* finish){
        const char delimiters[] = ",(";
        const char* it;
        vector<string> result;
    
        do{
            for (it = find_first_of(start, finish, begin(delimiters), end(delimiters));
                it != finish && *it == '(';
                it = find_first_of(extractParenthesis(it, finish) + 1, finish, begin(delimiters), end(delimiters)));
            auto&& temp = interpolate(start, it);
            result.insert(result.end(), temp.begin(), temp.end());
            start = ++it;
        } while (it <= finish);
        return result;
    }
    
    vector<string> interpolate(const char* start, const char* finish){
        vector<string> result{ 1, string{ start, find(start, finish, '(') } };
    
        for (auto it = start + result[0].size();
            it != finish;
            it = find(++start, finish, '('),
            for_each(result.begin(), result.end(), [&](string& i){ i += string{ start, it }; })){
            start = extractParenthesis(it, finish);
    
            auto temp = split(next(it), start);
            const auto size = result.size();
    
            result.resize(size * temp.size());
    
            for (int i = result.size() - 1; i >= 0; --i){
                result[i] = result[i % size] + temp[i / size];
            }
        }
        return result;
    }
    

    根据您的编译器,您需要转发声明这些,因为它们互相调用。如果输入字符串格式错误,这也会很奇怪。并且它无法处理转义的控制字符。

    无论如何你可以这样称呼它:

    const char test[] = "((a,b,c)o(m,v)p,b)";
    auto foo = interpolate(begin(test), end(test));
    
    for (auto& i : foo){
        cout << i << endl;
    }