execute compile time-compiled regex 在编译时

Execute compile time-compiled regex at compile time

我尝试编译这段代码时遇到编译错误:

import std.regex;
enum truth = "baba".matchFirst(ctRegex!`[ab]+$`) ? true : false;
void main() {}

/usr/local/Cellar/dmd/2.067.1/include/d2/std/regex/package.d(671): Error: malloc cannot be interpreted at compile time, because it has no available source code

如何解决这个问题?

你不能,正则表达式可以在编译时编译,但不能运行。您必须以其他方式编写匹配项,可能是 indexOf 或其他更简单函数的组合。 (不是因为regex太复杂,而是因为它内部调用了malloc来提高效率,编译时不支持,因为它是一个外部C函数。)

了解 ctRegex 需要一些解释 Phobos 的正则表达式引擎。它分两步工作:给定一个正则表达式,它首先将其编译成一些字节码,然后在字符串上匹配它,它 运行 就是那个代码。

在普通的 regex 中,这两个步骤都发生在 运行 时间。当您构建正则表达式对象时,它会将其编译成字节码。然后,当您匹配一个字符串时,它 运行 就是那个代码。

对于 ctRegex,第一部分发生在编译时,但第二部分仍然发生在 运行 时。因此,它在编译 D 时将正则表达式编译成字节码……然后将该字节码推送到 D 编译器的其余部分,以优化为完全本机代码。这就是它可以提供的好处。 (顺便说一句,差异通常并不重要,您应该对输入字符串进行基准测试,看看哪个更好。)

通常,CTFE(编译时函数求值)意味着运行时间代码在编译时也可以是运行,但前提是源代码可用。 malloc 不是这种情况,这就是为什么错误会这样说。


所以答案将取决于您的正则表达式是什么。您可能想要简化它并根据其他字符串 and/or std.algorithm 函数重写它。

...或重写 std.regex 源代码以摆脱那些 malloc 调用。将它们替换为 newif(_ctfe) 以开始。不过,我之前已经尝试过这样做,除非从那以后代码被重构,否则你只会遇到另一个问题:为了 运行time performance,std.regex 也使用 union 之类的东西,这也是ctfe 不支持...您必须重写其中的一部分,并注意不要在过程中损害 运行 时间性能。

使用其他函数处理您的具体情况可能更容易。