【问题标题】:Compiletime build up of std::regexstd::regex 的编译时构建
【发布时间】:2017-03-18 13:14:43
【问题描述】:

由于我在编译时知道正则表达式,并且构建正则表达式的时间为 O(2^m),其中 m 是正则表达式的长度,我很想在编译时构建正则表达式。

std::regex 可以做到这一点吗? (我不这么认为,因为我没有看到 constexpr 的任何 basic_regex 构造函数)

如果没有,是否有一个正则表达式库可以在编译时构建我的正则表达式?

【问题讨论】:

    标签: c++ regex c++11 compile-time-constant


    【解决方案1】:

    我们需要区分program编译和regex编译。后者实际上是在程序运行时完成的,它意味着构建一个适合快速匹配各种字符串的大型但高效的结构(状态机)。

    在c++11的正则表达式中,当你构造一个字符串的正则表达式对象时,就完成了正则表达式的编译:

    std::regex e (your_re_string);
    

    如果您在regex_matchregex_searchregex_replace 中使用这样的对象,您可以利用已经编译的正则表达式。因此,如果您在程序编译时知道您的字符串,那么为了提高速度,您可以做的最好的事情是在每次程序运行时构造一个相应的正则表达式对象,例如,将其声明为带有初始化程序的静态变量:

    static  std::regex e (your_constant_re_string);
    

    也许这就是你想要的。

    某些形式的regex_match, ... 函数可能会立即与正则表达式字符串一起使用。但是请注意,虽然它通常对程序员来说更方便,但如果你使用它们,每次调用这样的函数时都进行正则表达式编译,性能会受到影响。

    附:如果你真的,真的,真的想让你在程序编译时编译正则表达式,你可以 (1) 使用外部 regexp/lexer 编译器软件(如 https://github.com/madelson/PrecompiledRegex.Fody、Flex https://en.wikipedia.org/wiki/Flex_(lexical_analyser_generator) 或类似软件) (2)编译一个std::regex对象,然后序列化并转换为C++输入(其实就是(1)的DIY版) 但我很确定,如果只是为了在每次程序运行时保存一个正则表达式编译,它是不值得的。也许除非你真的有压倒性的表情。

    【讨论】:

    • 感谢您的回答。但是不应该在编译时为正则表达式构建 nfa/dfa 吗?我认为使用 C++11 和 constexpr 这应该是可能的。
    • 理论上是的,但你应该编写 constexpr 构造函数或等待它被添加。截至 2014 年,它预计在 C++14 或 C++17 中。我仍然不确定它是否已添加。如果没有,你可以贡献它。这是技术工作,但可能会出现某些运营商还不支持 constexpr。请记住,C++ 标准总是领先于它们的实现 :)
    • 如果我想要这样的编译器,我只需编写一个函数“storeAsCPPSource(const regex&)”并制作一个简单的应用程序来编译和存储对象。
    【解决方案2】:

    Hana Dusikova "Regular Expressions Redefined in C++” 在 CppCon 2017 的一次闪电演讲中描述了一种编译时正则表达式的方法,该方法使用用户定义的正则表达式字符串文字和生成匹配函数的编译时方法。 code is on GitHub,但目前仍处于试验阶段且流动性很强。因此,编译时正则表达式似乎很快就会出现。

    【讨论】:

    • 目前情况如何?
    • 针对 C++23 中的标准库提出的建议:open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1433r0.pdf 我相信该代码可以在 C++17 和 C++20 上按原样使用。
    • 谢谢,所以我们可能要等到 C++23?
    • 建议包含在 C++23 标准库中。查看我的答案中链接的 github 存储库,了解您现在可以使用的当前代码。 AFAIK 它应该适用于大多数当前的 C++ 实现,但我自己没有尝试过。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-29
    • 2019-11-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-16
    相关资源
    最近更新 更多