无限输入的正则表达式

时间:2018-12-09 19:12:27

标签: c++ regex sockets c++11 infinite

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

假设我们有一个非常简单的协议,一个请求包含STARTSTOP
实际的协议当然要复杂得多,但是为了举例说明,它会做到。

// 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

比方说,客户端发送单词START,等待5秒钟,然后发送另一个字符,例如X。在这种情况下,方法1将等待5秒钟,然后返回false。现在,假设客户端在原始START消息之后不发送任何消息,方法1将永远不会返回。
关于方法2:假设您的输入是XSTART,解析器似乎无法理解永远不会找到有效的匹配项,因为正则表达式以^开头,并且输入是无限的它也永远不会终止。
因此,最后,方法#1正确地标识了无效请求,而方法#2正确地标识了有效请求,但是方法#1在有效请求后陷入了无限循环,方法#2在无效请求中陷入了

https://leetcode.com/problems/two-sum/演示了问题:

#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");
}

一种解决方案是在(例如)第二个非活动状态之后向数据添加虚假端。但这会大大增加响应时间,而且感觉不对。
另一个解决方案是编写一个自定义的regex解析器,但是为这种简单的问题重新发明轮子似乎是过大的选择。
有没有更好的方法可以完成这项工作?

1 个答案:

答案 0 :(得分:0)

使用std::regex_constants::match_continuous标志卢克。