扩展库 / xregex
xregex
文本处理基于 BBRE 的正则表达式。复用编译结果和执行缓存,提供捕获、模板与回调替换、逐项拆分、多模式集合;与 C 共用 XRT 的内存和错误模型。
编译与便捷入口
import xregex
auto route = xregex.compile("^/users/(?<id>[0-9]+)$")
auto matcher = route.matcher()
if matcher.full("/users/42") then
println(matcher.capture(route.captureIndex("id")).text)
end
| 接口 | 合同 |
|---|---|
compile(pattern, flags=0, maxPatternBytes=1048576, maxCaptures=4096) | 返回不可变 Regex。预算须大于零,捕获数量包含完整匹配组 0。 |
compileSet(patterns, flags=0, maxPatternBytes=1048576, maxCaptures=4096) | array<string> 输入,返回 RegexSet,允许空集合;预算按每个模式计算。 |
test(pattern, text, flags=0) / fullMatch(pattern, text, flags=0) | 一次性搜索或完整匹配,返回 bool;每次编译,没有隐式全局缓存。 |
valid(pattern) / escape(text) | 语法验证返回 bool;escape 返回正则字面量转义字符串,不是替换模板转义。 |
编译标志按位或组合:IGNORE_CASE=1、MULTILINE=2、DOT_ALL=4、UNGREEDY=8。
默认预算常量为 DEFAULT_MAX_PATTERN_BYTES、DEFAULT_MAX_CAPTURES;它们不是整个集合、输入、结果或 CPU 时间的统一预算。
匹配与捕获
所有位置和长度均按 UTF-8 字节计数,从零开始,区间为 [begin, endPos)。它们不是字符切片参数。
| 类型 / 成员 | 合同 |
|---|---|
Regex.valid / pattern / flags / captureCount | 有效性、模式原文、标志和包含组 0 的捕获数量。 |
captureName(index) / captureIndex(name) | 有效未命名捕获返回空串;名称不存在返回 -1;下标越界报 IndexError。 |
test(text, start=0) / fullTest(text) | 返回 bool;前者搜索,后者覆盖完整输入。 |
find(text, start=0) / matchAt(text, start=0) | 返回 RegexMatch?;后者要求从指定位置匹配,未命中均为 null。 |
findAll(text, start=0) | 返回 array<RegexMatch>,未命中为空数组。 |
matcher() | 创建 RegexMatcher,保留表达式引用并复用执行缓存。 |
RegexMatcher.find / at / full / next | find/at 参数为 text、start=0;full 接受 text;next 无参数。均返回 bool。空匹配按 UTF-8 标量推进。 |
RegexMatcher.valid / matched / capture(index=0) | 有效性、是否存在当前匹配、复制当前捕获;capture 要求有当前匹配。 |
RegexMatch.group / matched / begin / endPos / length / text | 捕获序号、参与状态、字节区间与独立字符串。未参与捕获与合法空捕获用 matched 区分。 |
XL matcher 在 find/at/full 时持有输入副本,next 不再复制全文。捕获结果可跨后续匹配和对象释放保留。 只需判断时使用 bool 接口,避免复制捕获。C 底层 matcher 借用输入,所有者必须保持输入有效。
替换与回调
Regex.replace(text, replacement, limit=-1) 支持 $0、$1、${name},$$ 表示字面量 $。
replaceFirst(text, replacement) 只替换一次。
import xregex
from xregex import RegexMatcher
auto digits = xregex.compile("[0-9]+")
println(digits.replaceWith("a1 b22", func(RegexMatcher current) as string
return "[" + current.capture().text + "]"
end)) // a[1] b[22]
replaceWith(text, func(RegexMatcher) as string fn, limit=-1) 同步调用回调,其返回值原样写入,不再次解释为模板。
limit=-1 为全部,0 不调用回调,其他负值非法。回调异常保留原类型;可以嵌套独立匹配,但应只读取传入 matcher,不重新搜索或推进它。
逐项拆分
Regex.splitter(text, limit=-1, includeCaptures=false, skipEmpty=false) 返回 RegexSplitter;
splitParts 使用相同参数,返回 array<RegexSplitPart>;
split(text, limit=-1, skipEmpty=false) 返回普通字段 array<string>。
limit 限制分隔匹配次数,不是结果项数;0 不使用匹配,-1 不限次数。skipEmpty 对普通字段和捕获项都过滤空文本。
底层标志为 SPLIT_CAPTURES=1、SPLIT_SKIP_EMPTY=2。
RegexSplitter 的 valid 表示句柄有效,next() 返回 RegexSplitPart?,结束后为 null。 RegexSplitPart 包含 text、capture、matched、isCapture;capture=-1 为普通字段。XL splitter 持有输入副本,C splitter 借用输入。 这是逐项输出接口,不是接收分块网络输入的增量解析器。
多模式集合
| 成员 | 合同 |
|---|---|
RegexSet.valid / count / regex(index) | 有效性、模式数量、取得带有独立引用的 Regex。 |
test(text, start=0) / matches(text, start=0) / first(text, start=0) | 返回 bool、命中索引数组、最小命中索引;未命中为 false、[]、-1。 |
matcher() as RegexSetMatcher | 复用集合执行缓存,search(text, start=0) 返回是否命中。 |
RegexSetMatcher.valid / count / first | 有效性、命中数量、最小命中模式索引。 |
index(index) / matched(pattern) / indices() | 读取第 index 项、查询指定模式、复制索引数组;非法模式索引 matched 返回 false,index 越界抛 IndexError。 |
结果按模式索引升序,不按文本出现顺序。集合经公开 xvalue API 读取 array<string>,完成编译后不再借用数组。
错误与资源
普通未命中不是异常。非法语法、标志、非正预算和 limit 为 ValueError;字节位置/下标越界为 IndexError; 原生资源超限为 RangeError;分配失败为 MemoryError。valid 只对非法语法返回 false,不吞掉内存或资源故障。
errorOffset(error value) 读取语法字节位置,errorPatternIndex(error value) 读取集合编译失败的模式索引;
没有对应信息或传 null 返回 -1。查询明确的 catch 错误对象,允许跨后续调用保存。
import xregex
try
xregex.compileSet(["ok", "("])
catch ValueError problem
println(xregex.errorPatternIndex(problem)) // 1
println(xregex.errorOffset(problem))
end
Regex/RegexSet 不可变;不同 matcher 可独立运行。同一可变 matcher、splitter 或 set matcher 必须串行访问。 Regex、RegexMatcher、RegexSplitter、RegexSet、RegexSetMatcher 的 nativeHandle() 都返回底层借用指针,不能重复接管或由 C 擅自释放。
C API 与双语范例
公共头为 extlibs/xregex/include/xregex.h。xrtRegexConfigInit、xrtRegexSplitConfigInit 初始化配置;
xrtRegexCompile、xrtRegexMatcher*、xrtRegexReplaceTo/ReplaceFuncTo、xrtRegexSplitter*、xrtRegexSet* 提供相同核心能力。
执行结果为 XREGEX_ERROR / XREGEX_NONE / XREGEX_MATCH 三态。
C 输入和捕获 xstrview 为借用;核心拥有型 str 使用 xrtFree,包装返回的 xbuffer* 使用 xrtBufferDestroy。 xrtRegexSetRegex 返回集合内借用表达式,独立保留需 xrtRegexRef;XL set.regex 已处理引用。
包使用 ERROR_FORMAT、IO_BUFFER、STRING_SPLIT、UNICODE、VALUE_CONTAINER。裁剪产物使用包内正则实现; 完整 C 环境已提供 XRT 正则时,不重复编译相同实现。所有原生编译单元必须采用一致的模块选择。
XL 教学:examples/extlibs/xregex.xl;对照:examples/extlibs/xregex_basic.xl
与 extlibs/xregex/examples/basic.c。共同预期为 examples/extlibs/xregex_basic.expected.txt。
发行包内 README 提供完整参数与运行命令。
验证范围
2026-09-27 限定基线覆盖 Windows C/XL、JIT/AOT、49 个实际生成的绑定原型、输入及捕获寿命、空匹配推进、 错误对象保留、回调异常与重入、逐点分配失败和双语黄金输出。门禁为 tools/check_extlib_xregex.ps1。
独立 Linux C 使用 ASan/UBSan 和泄漏检查,并核对 LP64 原型,门禁为 tools/check_extlib_xregex.sh。 不表示 Linux xlang JIT/AOT、32 位/ARM、同一可变对象并发或完整性能基准已验收。源码和构建变化后须重新验证。