news 2026/9/24 16:33:51

RE2 正则表达式库实战指南:安全优先的线性时间匹配引擎及其 C++ API 与安装部署

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
RE2 正则表达式库实战指南:安全优先的线性时间匹配引擎及其 C++ API 与安装部署

RE2 正则表达式库实战指南:安全优先的线性时间匹配引擎及其 C++ API 与安装部署

【免费下载链接】re2RE2 is a fast, safe, thread-friendly alternative to backtracking regular expression engines like those used in PCRE, Perl, and Python. It is a C++ library.项目地址: https://gitcode.com/gh_mirrors/re21/re2

RE2 是一个以安全性为首要目标的高效正则表达式 C++ 库,自 2006 年起在 Google 及众多生产环境中投入使用。它以"匹配时间与输入长度成线性关系"为核心保证,能够安全地处理来自不可信用户的正则表达式。本文将围绕仓库根目录下的 README.md 展开,完整介绍 RE2 的设计哲学、POSIX/Perl 双语法模式、FullMatch/PartialMatch/Consume等匹配接口、RE2::Options配置体系,并结合 re2/re2.h、Makefile、CMakeLists.txt 等源码给出 GNU make、CMake、Bazel 三种安装方式的完整步骤;读完本文,你将掌握 RE2 的核心 API 用法与底层实现原理,能够在自己的 C++ 项目中安全、高效地接入并配置 RE2。

为什么需要 RE2:安全性优先的线性时间保证

正如 README.md 开篇所强调的——"Safety is RE2's primary goal"(安全性是 RE2 的首要目标)。RE2 从设计之初就明确了一个目标:能够无风险地处理来自不可信用户的正则表达式。其核心保证之一是:

匹配时间与输入字符串的长度呈线性关系(linear in the length of the input string)。

这一保证从实现层面由三个关键机制共同支撑(参见 re2/re2.h 中RE2::Options的注释,第 642–668 行):

  • 可配置的内存预算(configurable budget):解析器(parser)、编译器(compiler)与各执行引擎(execution engines)都在一个可配置的内存上限内工作,预算耗尽时优雅失败(failing gracefully),而不是失控膨胀;
  • 避免递归(eschewing recursion):RE2 不依赖递归,从根本上规避了栈溢出风险;
  • DFA/NFA 双引擎与回退机制:每个 RE2 对象会编译出正向与反向两个 Prog(程序),并可为每个 Prog 维护 DFA 缓存;一旦 DFA 缓存超出预算被频繁刷新,RE2 会自动回退到 NFA 实现继续执行。

在 re2/re2.h 中,默认内存预算常量被定义为kDefaultMaxMem = 8<<20(即 8 MiB,第 671 行)。README 也明确指出:处理来自不可信用户的表达式是 RE2 的设计初衷,这让它特别适合 Web 防火墙、输入校验、日志过滤等面向外部输入的场景。

设计哲学:悲观求稳,而非盲目求快

README 坦诚地说明:RE2 的目标并不是在所有情况下都比其他引擎更快。虽然它保证了渐近线性(asymptotically linear)的匹配时间,但更复杂的表达式会带来更大的常数因子,更长的表达式也会增加安全处理的额外开销。

README 用"悲观主义 vs 乐观主义"做了精辟的类比:

  • 回溯引擎(如 PCRE、Perl、Python 的 re)是乐观的:它顺序测试每个备选分支,当第一个分支命中率最高时表现最快;
  • RE2 是悲观的:它并行地评估所有备选分支,避免了"最后一个分支慢"的惩罚,代价是固定的额外开销——正是这种"悲观",换来了 RE2 的安全性。

因此 RE2 还坚持另一项原则:不支持任何目前仅存在回溯解法的构造。具体而言,反向引用(backreferences)和环视断言(look-around assertions)不被支持(子匹配提取 submatching 不受影响)。这一点在 re2/re2.h 的语法说明注释(第 13–21 行)中同样得到印证:"backreferences and generalized assertions are not available"。关于正则表达式理论背景,README 推荐了 Russ Cox 关于正则匹配的三篇经典文章(《Regular Expression Matching Can Be Simple And Fast》《Regular Expression Matching: the Virtual Machine Approach》《Regular Expression Matching in the Wild》),此处不再赘述。

支持的语法:POSIX 模式与 Perl 模式

根据 README 的"Syntax"一节,RE2 支持两套语法模式:

模式语法范围匹配语义
POSIX 模式标准 POSIX(egrep)语法返回最左最长(leftmost-longest)匹配
Perl 模式(默认)大多数 Perl 运算符返回与 Perl 相同的匹配结果

被排除的仅有那些需要回溯(及其潜在指数级运行时间)才能实现的运算符,包括反向引用和广义断言(generalized assertions)。

仓库内附有完整的语法参考文档 doc/syntax.txt(及其 HTML 版本 doc/syntax.html),详细记录了 Perl 模式下受支持的全部语法。此外,re2/re2.h 的注释给出了几个最常见的扩展运算符示例(C++ 普通字符串字面量中需使用双反斜杠):

"hello (\\w+) world" // \w 匹配一个"单词"字符 "version (\\d+)" // \d 匹配一个数字 "hello\\s+world" // \s 匹配任意空白字符 "\\b(\\w+)\\b" // \b 在单词边界处匹配非空字符串 "(?i)hello" // (?i) 开启大小写不敏感匹配 "/\\*(.*?)\\*/" // .*? 尽可能少地匹配

如果使用 C++11 原始字符串字面量(raw string literal),则无需转义:

R"(hello (\w+) world)" R"(version (\d+))" R"(hello\s+world)" R"(\b(\w+)\b)" R"((?i)hello)" R"(/\*(.*?)\*/)"

C++ API 实战

RE2 的原生语言是 C++(re2/re2.h 是核心头文件,总接口约 1074 行),完整公开接口可直接阅读该头文件。下面按 README 的章节逐一展开,并结合头文件补充实现细节。

基本匹配操作:FullMatch 与 PartialMatch

RE2 提供两个基本操作符(定义见 re2/re2.h 第 411–429 行):

  • RE2::FullMatch:要求正则表达式与整个输入文本完全匹配;
  • RE2::PartialMatch:在输入文本的某个子串中寻找匹配;POSIX 模式下返回最左最长匹配,Perl 模式下返回与 Perl 相同选择的匹配。

README 给出的示例:

assert(RE2::FullMatch("hello", "h.*o")) assert(!RE2::FullMatch("hello", "e")) assert(RE2::PartialMatch("hello", "h.*o")) assert(RE2::PartialMatch("hello", "e"))

从 re2/re2.h 的实现看,FullMatch/PartialMatch内部通过变参模板(variadic templates)把每个参数包装成RE2::Arg对象,再调用FullMatchN/PartialMatchN数组版接口执行(第 348–368、410–429 行),这是下文"可变参数匹配"一节的基础。

子匹配提取(Submatch Extraction)

两个匹配函数都接受额外指针参数用于存放子匹配结果。README 说明参数类型可以是:

  • string*
  • 整数类型
  • absl::string_view*(与std::string_view非常相似,因历史原因 RE2 使用前者)

string_view本质上是"指向原始输入文本的指针 + 长度计数",行为类似字符串但不携带自身存储。**注意:**与使用指针类似,一旦原始文本被删除或超出作用域,就不能再使用该string_view

README 给出的完整示例(含多种成功/失败路径):

// 成功解析。 int i; string s; assert(RE2::FullMatch("ruby:1234", "(\\w+):(\\d+)", &s, &i)); assert(s == "ruby"); assert(i == 1234); // 失败:"ruby" 不能被解析为整数。 assert(!RE2::FullMatch("ruby", "(.+)", &i)); // 成功;不提取数字。 assert(RE2::FullMatch("ruby:1234", "(\\w+):(\\d+)", &s)); // 成功;跳过 NULL 参数。 assert(RE2::FullMatch("ruby:1234", "(\\w+):(\\d+)", (void*)NULL, &i)); // 失败:整数溢出,导致值无法存入 i。 assert(!RE2::FullMatch("ruby:123456789123", "(\\w+):(\\d+)", &s, &i));

结合 re2/re2.h 的接口注释(第 384–409 行),可提取参数类型可总结为:

参数类型行为
std::string匹配片段被拷贝进字符串
absl::string_view被修改为指向匹配片段
std::optional<T>处理"可选子模式未出现"的情况(如(\d+)?未匹配时)
各种标量数值类型文本按十进制解析后存入
定义了bool T::ParseFrom(const char*, size_t)的类型调用其ParseFrom解析
(void*)NULL忽略对应的捕获子串

需要特别注意的是(README 与头文件注释均强调):FullMatch返回true当且仅当同时满足三个条件——(a) 文本与正则完全匹配;(b) 匹配到的子模式数量提供的指针参数数量;(c) 第 i 个参数类型能容纳第 i 个捕获子串。另外,可选子模式未匹配时被赋值为空串(null string),因此RE2::FullMatch("abc", "[a-z]+(\\d+)?", &number)会返回false——因为"不存在字符串"(连空串都不是)无法解析为数字;此时应改用std::optional<int>(re2/re2.h 第 401–409 行)。

预编译正则表达式:RE2 对象复用

上述示例每次调用都会重新编译正则表达式。性能敏感场景下,可以一次性编译为RE2对象并反复复用(README 明确指出:预编译后通常能比sscanf更快地解析文本):

RE2 re("(\\w+):(\\d+)"); assert(re.ok()); // 编译成功;若失败,可查看 re.error(); assert(RE2::FullMatch("ruby:1234", re, &s, &i)); assert(RE2::FullMatch("ruby:1234", re, &s)); assert(RE2::FullMatch("ruby:1234", re, (void*)NULL, &i)); assert(!RE2::FullMatch("ruby:123456789123", re, &s, &i));

从 re2/re2.h 看,RE2对象被明确设计为多线程并发安全("An RE2 object is safe for concurrent use by multiple threads",第 237–238 行),且不可拷贝、不可移动(第 292–304 行);注释建议需要共享时使用std::shared_ptr<RE2>std::unique_ptr<RE2>。对象还提供一组诊断接口(第 306–335 行):

  • re.ok():是否成功创建;
  • re.pattern():原始模式串;
  • re.error()/re.error_code()/re.error_arg():失败时的错误信息、错误码(ErrorCode枚举,第 248–269 行,覆盖ErrorBadEscapeErrorBadCharClassErrorMissingParenErrorBadUTF8ErrorPatternTooLarge等)与出错片段;
  • ProgramSize()/ReverseProgramSize()/ProgramFanout():程序大小与扇出直方图,近似衡量正则的"成本"。

进阶匹配接口:Consume、FindAndConsume 与 Match

除了两个基本操作符,re2/re2.h 还提供增量扫描接口:

  • RE2::Consume(&input, pattern, ...)(第 444–447 行):要求正则匹配文本的前缀,成功后input前进到匹配文本之后,可用于反复解析"var = value"这样的行流:
    std::string contents = ...; // 填充字符串 absl::string_view input(contents); // 用 string_view 包装 std::string var; int value; while (RE2::Consume(&input, "(\\w+) = (\\d+)\n", &var, &value)) { ...; }

    头文件特别提醒:如果正则可能匹配空字符串,循环体会无限空转,必须自行检查空匹配并推进或跳出循环(第 162–167 行)。

  • RE2::FindAndConsume(&input, pattern, ...)(第 462–465 行):与Consume类似但不锚定在开头,例如反复调用RE2::FindAndConsume(&input, "(\\w+)", &word)可提取字符串中的所有单词。
  • RE2::Match(text, startpos, endpos, anchor, submatch, nsubmatch)(第 585–590 行):最通用的底层匹配例程,支持指定起始/结束偏移与锚定方式(Anchor枚举:UNANCHORED/ANCHOR_START/ANCHOR_BOTH,第 542–546 行),并直接填充absl::string_view数组。头文件提示:请求的子匹配信息越少运行越快nsubmatch == 0最快,nsubmatch == 1次之),且失败时submatch[]也可能被改写。

Options:预定义选项与完整配置体系

RE2构造函数接受可选的第二参数来改变默认选项。README 首先介绍了三个预定义选项(对应 re2/re2.h 的CannedOptions枚举,第 276–281 行):

RE2 re("(ab", RE2::Quiet); // 解析失败时不向 stderr 输出错误 assert(!re.ok()); // 仍可通过 re.error() 查看详情
  • RE2::Quiet:静默解析错误(不打印日志),默认log_errors为 true 时会输出;
  • RE2::Latin1:禁用 UTF-8,按 Latin-1 解释文本与模式;
  • RE2::POSIX:使用 POSIX 语法与最左最长匹配。

如果需要更细粒度控制,可以自己声明RE2::Options对象并逐项配置。完整选项清单与默认值定义在 re2/re2.h 第 618–755 行的RE2::Options类中:

选项默认值含义
utf8true文本与模式按 UTF-8 解释;否则按 Latin-1
posix_syntaxfalse将正则限制为 POSIX egrep 语法
longest_matchfalse搜索最长匹配而非首个匹配
log_errorstrue语法与执行错误记录到 ERROR 日志
max_mem8<<20(8 MiB)RE2 的大致最大内存占用
literalfalse将字符串按字面量解释,而非正则
never_nlfalse即使模式中有\n也永不匹配换行
dot_nlfalse.匹配包括换行在内的一切
never_capturefalse所有括号都解析为非捕获组
case_sensitivetrue大小写敏感匹配(正则内可用(?i)覆盖,POSIX 模式下除外)
perl_classesfalse允许 Perl 的\d \s \w \D \S \W(仅 POSIX 模式下生效)
word_boundaryfalse允许 Perl 的\b \B(仅 POSIX 模式下生效)
one_linefalse^$仅匹配文本首尾(仅 POSIX 模式下生效)

其中perl_classesword_boundaryone_line三项只在posix_syntax == true时被参考;非 POSIX 模式下这些特性始终开启且无法关闭,此时要做多行匹配需在正则开头加(?m)

关于max_mem,re2/re2.h 的注释给出了非常具体的预算分配机制(第 642–668 行):

  • 每个 RE2 拥有两个 Prog(正向、反向),每个 Prog 可带两个 DFA(首个匹配、最长匹配),共 4 个 DFA;
  • 预算在两者间静态分配:2/3 给正向 Prog,1/3 给反向 Prog;正向 Prog 将其余量的一半分给每个 DFA,反向 Prog 全部给它的最长匹配 DFA;
  • 一旦某个 DFA 填满预算,会清空缓存重新开始;若这发生得过于频繁,RE2 就回退到 NFA 实现

这一机制是"内存可控、优雅失败"设计承诺的直接代码级证据。

可变参数匹配:FullMatchN 系列

当正则表达式是运行时动态计算、捕获组数量无法在写代码时确定时,可以使用数组版(N 后缀)接口(re2/re2.h 第 348–355 行):

const RE2::Arg* args[10]; int n; // ... 用指向 RE2::Arg 对象的指针填充 args ... // ... 将 n 设为 RE2::Arg 对象的数量 ... bool match = RE2::FullMatchN(input, pattern, args, n);

它等价于RE2::FullMatch(input, pattern, *args[0], *args[1], ..., *args[n - 1])PartialMatchNConsumeNFindAndConsumeN同理。

解析十六进制、八进制与 C 进制数字

默认情况下,向匹配函数传入数值类型指针时,文本按十进制解析。如需其他进制,可用三个运算符包装指针(re2/re2.h 第 196–209、762–766 行):

int a, b, c, d; RE2::FullMatch("100 40 0100 0x40", "(.*) (.*) (.*) (.*)", RE2::Octal(&a), RE2::Hex(&b), RE2::CRadix(&c), RE2::CRadix(&d)); // 结果:a、b、c、d 均为 64
  • RE2::Hex(ptr):按基 16 解析;
  • RE2::Octal(ptr):按基 8 解析;
  • RE2::CRadix(ptr):遵循 C 语言风格前缀——0开头按八进制、0x开头按十六进制、否则按十进制。

替换、提取与转义:Replace / GlobalReplace / Extract / QuoteMeta

re2/re2.h 还提供了字符串变换接口(第 467–520 行):

  • RE2::Replace(&str, re, rewrite):替换第一个匹配。rewrite 中\1\9可引用对应捕获组,\0表示整个匹配文本。例如:
    std::string s = "yabba dabba doo"; RE2::Replace(&s, "b+", "d"); // s 变为 "yada dabba doo"
  • RE2::GlobalReplace(&str, re, rewrite):替换所有不重叠的匹配("banana"中替换"ana"只会发生一次),返回替换次数。如"yabba dabba doo"中替换"b+""d""yada dada doo"
  • RE2::Extract(text, re, rewrite, &out):提取匹配文本并应用 rewrite 写入outtext不得与*out别名)。
  • RE2::QuoteMeta(unquoted):转义字符串中所有正则元字符,返回值作为正则使用时精确匹配原字符串,例如1.5-2.0?转义为1\.5\-2\.0\?

配合使用前,可用CheckRewriteString校验 rewrite 串的合法性,用MaxSubmatch获取 rewrite 需要的最大捕获组编号(第 592–615 行)。

Unicode 规范化说明

README 专门指出:RE2 按Unicode 码点(code point)操作,不做任何规范化(normalization)。例如正则/ü/(U+00FC,带分音符的 u)不会匹配输入"ü"(U+0075 U+0308,u 后跟组合分音符)。如果你确实需要此类匹配,最简单的方案是在使用 RE2 之前对正则与输入做一次预处理规范化(Unicode 规范化规范详见 Unicode TR15)。

附加提示:LazyRE2、RE2::Set、PossibleMatchRange 与 hooks

README 指引高级用法(构造自定义参数列表、把 RE2 用作词法分析器、解析十六/八/C 进制数字等)参见 re2/re2.h,该头文件还包含若干值得注意的进阶设施:

  • LazyRE2(第 986–1019 行):安全地编写全局/静态 RE2 的辅助类型。用static LazyRE2 re = {".*"};替代static RE2 re(".*");,前者借助absl::call_once保证多线程安全,且设计上永不析构其构造的 RE2(适用于全局与函数静态变量):
    static LazyRE2 re = {".*"}; // 之后用 *re 代替 re 使用
  • RE2::Set(定义于 re2/set.h):一个同时搜索多组正则的集合类型。先Add(pattern, &error)添加(返回从 0 开始递增的索引,解析失败返回 -1),再Compile()编译,最后Match(text, &v)一次性获得所有命中正则的索引列表(结果无序)。常用于防火墙规则匹配、多关键字过滤等场景。顺带一提,re2/stringpiece.h 中re2::StringPiece目前是absl::string_view的别名,老代码可继续通过该头文件使用。
  • PossibleMatchRange(min, max, maxlen)(第 536–537 行):计算所有可能匹配字符串的字典序范围,可用于预过滤器。
  • hooks命名空间(第 1021–1067 行):通过SetDFAStateCacheResetHook/SetDFASearchFailureHook挂钩 DFA 缓存重置与搜索失败事件,便于观测引擎行为。

安装与构建:make、CMake、Bazel 三选一

README 说明 RE2 可以用GNU make、CMake 或 Bazel构建与安装。构建 RE2 需要C++17 编译器Abseil库;构建测试与基准需要GoogleTestBenchmark

使用 GNU make

最简安装流程(README 原文):

make make test make benchmark make install make testinstall

从 Makefile 可以看到更多细节:

  • 编译参数硬性要求-std=c++17 -pthread(第 52 行),且通过pkg-config自动发现 Abseil 依赖(ABSL_DEPS,第 6–21 行);
  • 静态库与动态库并行产出:obj/libre2.aobj/so/libre2.$(SOEXT)(第 110 行),动态库的 ABI 版本(SONAME)为11(第 85 行),共享库符号受 libre2.symbols(Linux/SunOS)与 libre2.symbols.darwin(macOS)约束;
  • make test会构建并运行 debug、static、shared 三套测试(第 288–301 行),通过仓库自带的 runtests 脚本执行;
  • make benchmark构建obj/test/regexp_benchmark(源码位于 re2/testing/regexp_benchmark.cc),make fuzz可构建 re2/fuzzing/re2_fuzzer.cc 模糊测试器;
  • make testinstall会基于 testinstall.cc 编译两个小程序,分别链接静态库与动态库并运行,验证安装后的库确实可用(第 350–384 行)。

获取依赖(README 给出的各平台命令):

  • Linux:apt install libabsl-dev libgtest-dev libbenchmark-dev
  • macOS:brew install abseil googletest google-benchmark pkg-config-wrapper
  • Windows:vcpkg install abseil gtest benchmarkvcpkg add port abseil gtest benchmark

使用 CMake

如果标准 Makefile 在依赖查找上遇到麻烦,切换 CMake 往往能解决:

rm -rf build cmake -DRE2_TEST=ON -DRE2_BENCHMARK=ON -S . -B build cd build make make test make install

CMake 相关说明(源自 README 与 CMakeLists.txt 第 16–36 行的option()声明):

  • RE2_TEST=ON:构建并运行测试;
  • RE2_BENCHMARK=ONmake test会构建并运行测试二进制,同时构建regexp_benchmark基准二进制但不运行它;
  • 若完全不需要测试与基准,可省略对应-D参数,此时也不需要 GoogleTest 与 Benchmark 依赖
  • RE2_USE_ICU=ON:引入 ICU Unicode 库依赖,同时扩展\p\P模式可用的属性名列表(Makefile 第 30–33 行也预留了CCICU/LDICU的同等开关);
  • CMake 还可生成Visual Studio 与 Xcode 工程,以及 Cygwin、MinGW、MSYS 的 makefile。注意事项:Visual Studio 用户需要 2019 或更高版本;Cygwin 用户必须从 Cygwin 命令行运行 CMake,而非 Windows 命令行。

若要将 RE2 引入你自己的 CMake 工程,README 提示 CMake 依赖有两种方式:add_subdirectory()(依赖的源码位于你工程的子目录中)与find_package()(依赖的二进制已安装到系统上);无论哪种方式,target_link_libraries(... re2::re2)都可以直接使用。工程级配置还可在 re2.pc.in(pkg-config 模板)与 re2Config.cmake.in 中查看。

使用 Bazel

如果使用 Bazel,依赖(包括 Abseil)会由构建系统自动处理,你只需下载 Bazel 本身,可用 Bazelisk 管理版本:

go install github.com/bazelbuild/bazelisk@latest # 或 macOS:brew install bazelisk bazelisk build :all bazelisk test :all

仓库根目录提供了 WORKSPACE.bazel、WORKSPACE.bzlmod、MODULE.bazel 与 BUILD.bazel 等 Bazel 工程文件。若从其他项目使用 RE2,需要确保至少使用C++17。此外,用源码内附的 app 目录(TypeScript + Rollup 的最小示例)可从另一角度观察 RE2 的绑定使用方式,但注意它并非官方主推的绑定。

Python 官方封装:google-re2

README 明确指出:RE2 的官方 Python 封装位于仓库 python 目录,并发布在 PyPI 上,名为google-re2注意:PyPI 上还有一个re2包,但它并非 RE2 作者维护且已停止维护,请使用google-re2

从 python/re2.py 看,该模块是 Python 标准re模块的即插即用替代品(drop-in replacement),底层通过 pybind11 绑定 python/_re2.cc。关键特性:

  • 同样不支持反向引用、环视断言等需要回溯的特性;已知差异之一是 PCRE 的\Z需要改写为 RE2 的\z(README 见 python/README,差异清单见 python/re2.py 第 1–27 行);
  • Options类以可读写属性的形式暴露 RE2 的全部 13 项选项(max_memencodingposix_syntaxlongest_matchlog_errorsliteralnever_nldot_nlnever_capturecase_sensitiveperl_classesword_boundaryone_line,第 45–59 行);
  • API 对齐re模块:compile/search/match/fullmatch/finditer/findall/split/sub/subn/escape(第 62–120 行);
  • 模块内部维护一个LRU 缓存(最多 128 个已编译正则对象),每个对象的底层 RE2 默认占用至多 8 MiB,因此缓存默认至多约 1 GiB(实际通常远小于此,第 23–26 行)。

构建该封装需要 Python 3、pybind11(以及系统已安装的 RE2,Debian 下为libre2-dev),细节见 python/setup.py 与 python/README。

端口与封装一览

RE2 以 C++ 实现,官方 Python 封装即上文所述google-re2。除此之外,社区还提供了众多非官方封装与移植,README 中列出的包括(此处仅列名称,官方维护的移植另有说明):

  • C:cre2;D:re2d(DUB 上发布);Erlang:re2(Hex 上发布);Inferno:inferno-re2;
  • Node.js:node-re2(NPM 上发布);OCaml:re2(OPAM 上发布,Janestreet 维护);Perl:re-engine-RE2(CPAN 上发布);R:re2(CRAN 上发布);Ruby:re2(RubyGems 上发布);WebAssembly:re2-wasm(NPM 上发布);
  • RE2J:RE2 C++ 代码到纯 Java 的移植;RE2JS:RE2J 到 JavaScript 的移植;
  • Go 的regexp包与 Rust 的regexcrate 虽与 RE2不共享代码,但遵循相同原理、接受相同语法并提供相同的效率保证。

测试与验证

RE2 附带极其完备的测试套件(re2/testing 目录),覆盖解析(re2/testing/parse_test.cc)、编译(re2/testing/compile_test.cc)、DFA(re2/testing/dfa_test.cc)、搜索(re2/testing/search_test.cc)、字符类(re2/testing/charclass_test.cc)、正则化简(re2/testing/simplify_test.cc)、API 参数(re2/testing/re2_arg_test.cc)等,另有 exhaustive 系列(re2/testing/exhaustive_test.cc 及 exhaustive1/2/3)对海量正则-文本组合做穷举验证,以及 re2/testing/random_test.cc 随机测试。核心 API 的行为断言(如子匹配、整数溢出失败、NULL跳过等)与 README 中的示例完全一致,可直接在 re2/testing/re2_test.cc 中找到对应用例作为印证。

更多仓库内资料

  • 完整语法参考:doc/syntax.txt、doc/syntax.html;
  • 核心 API 头文件:re2/re2.h、re2/set.h;
  • 构建配置:Makefile、CMakeLists.txt、BUILD.bazel、MODULE.bazel;
  • 封装与测试:python、re2/testing、runtests、testinstall.cc。

关于社区讨论与代码变更动态,README 推荐使用官方 issue 跟踪器与 re2-dev 邮件列表;向项目提交变更前请先阅读贡献指南,并注意 RE2 项目不使用 GitHub pull request作为合入方式。

【免费下载链接】re2RE2 is a fast, safe, thread-friendly alternative to backtracking regular expression engines like those used in PCRE, Perl, and Python. It is a C++ library.项目地址: https://gitcode.com/gh_mirrors/re21/re2

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/24 16:33:09

四路can转4G在现场应用中有什么问题?

一、现场使用 SG‑CAN‑4G‑410 网关&#xff0c;电脑通过网口配置设备&#xff0c;配置软件搜索不到设备&#xff0c;需要从哪些方面排查处理。 首先确认设备供电正常&#xff0c;PWR 电源灯常亮&#xff0c;RUN 系统指示灯处于闪烁运行状态&#xff1b;电脑网线连接设备 LAN …

作者头像 李华
网站建设 2026/9/24 16:28:38

QzoneArchive Android构建指南:Tauri移动开发完整上手教程

QzoneArchive Android构建指南&#xff1a;Tauri移动开发完整上手教程 【免费下载链接】QzoneArchive 将 QQ 空间历史动态、照片、视频与互动记录安全归档到本地的桌面 / 移动端工具。 项目地址: https://gitcode.com/gh_mirrors/qz/QzoneArchive QzoneArchive 是一款将…

作者头像 李华