代码之家  ›  专栏  ›  技术社区  ›  DutChen18

无限输入上的正则表达式

  •  0
  • DutChen18  · 技术社区  · 7 年前


    我已经编写了一个自定义套接字迭代器,以便将数据传递给 std 的正则表达式函数。
    请记住,从理论上讲,数据可能永远不会结束,在发送完整的请求后,套接字不会关闭,因为客户端需要响应,并且可能需要将来的通信。

    让我们假设我们有一个非常简单的协议,一个请求由 START STOP
    真正的协议当然要复杂得多,但为了举例说明,这样就可以了。

    // A simple regular expression to parse this could be defined like so:
    static const std::regex re("^(START|STOP)");
    // And parsed using:
    std::regex_match(begin, end, result, re); // 1
    // or using regex_search
    std::regex_search(begin, end, result, re); // 2
    

    让我们假设客户发送消息 开始 ,等待5秒,然后发送另一个字符, X 例如在这种情况下,方法#1将等待5秒钟,然后返回false。现在假设客户机在原始文件之后没有发送任何内容 消息,方法#1将永远不会返回。
    至于方法2:假设您的输入是 XSTART ^ ,因为输入是无限的,所以它也不会终止。
    因此,最终方法1正确识别无效请求,而方法2正确识别有效请求,但方法1在有效请求时陷入无限循环,方法2在无效请求时陷入无限循环。

    Minimal, Complete, and Verifiable example

    #include <stdio.h>
    #include <stdint.h>
    #include <iterator>
    #include <vector>
    #include <regex>
    
    // stdin iterator that goes against all good
    // programming practices for the sake of simplicity
    class stdin_iter : public std::iterator<std::bidirectional_iterator_tag, char> {
        static std::vector<char> buf;
        size_t i;
    public:
        stdin_iter() : i(SIZE_MAX) {}
        stdin_iter(size_t i) : i(i) {}
        bool operator==(const stdin_iter& o) const { return i == o.i; }
        bool operator!=(const stdin_iter& o) const { return i != o.i; }
        value_type operator*() const {
            while (i >= buf.size()) buf.push_back(getc(stdin));
            return buf[i];
        }
        stdin_iter& operator++() { i++; return *this; }
        stdin_iter operator++(int) { stdin_iter r = *this; i++; return r; }
        stdin_iter& operator--() { i--; return *this; }
        stdin_iter operator--(int) { stdin_iter r = *this; i--; return r; }
    };
    std::vector<char> stdin_iter::buf;
    
    int main() {
        stdin_iter begin(0), end;
        std::regex re("^(START|STOP)");
        std::match_results<stdin_iter> result;
    
        //bool valid = std::regex_match(begin, end, result, re); // stuck on valid input
        //bool valid = std::regex_search(begin, end, result, re); // stuck on invalid input
        bool valid = std::regex_search(begin, end, result, re, std::regex_constants::match_continuous); // mostly works
    
        if (valid) printf("valid: %s\n", result[1].str().c_str());
        else printf("invalid\n");
    }
    

    一种解决方案是在(例如)第二次不活动后向数据添加人工端。但这大大增加了响应时间,感觉不太对劲。
    另一个解决方案是编写一个定制的正则表达式解析器,但为这么简单的问题重新设计轮子似乎有些过火。
    有没有更好的方法来实现这一点?

    1 回复  |  直到 7 年前
        1
  •  0
  •   DutChen18    7 年前

    std::regex_constants::match_continuous 旗帜,卢克。