技术手册
正则匹配与替换
用一个最小示例理解查找、捕获组、替换模板和跨端验证。
跟 AI 创作助手说想要什么效果,它会写好正则(见第 9 关)。这一页讲正则怎么工作、怎么检查。
正则负责找到格式固定的文字,再把它替换成另一段文字或 HTML。它不会让 AI 自动遵守输出格式,所以第一步永远是确认原始回复稳定。
先完成一次替换
假设角色回复中包含:
<status>地点:玻璃温室</status>在角色的正则编辑器新增一条规则:
| 设置 | 填写内容 |
|---|---|
| 规则名称 | 地点状态卡 |
| 应用于 | AI 消息 |
| 查找 | <status>([\s\S]*?)</status> |
| flags | g |
| 替换 | <aside class="status-card">$1</aside> |
把原始文本粘贴到测试面板,预期结果是:
<aside class="status-card">地点:玻璃温室</aside>看到这个结果,说明文本转换正确。接下来还要给 .status-card 添加 CSS,才能得到卡片外观。
$1 是什么
查找表达式中的括号会保存匹配内容:
<status>([\s\S]*?)</status>
└────$1────┘替换模板中的 $1 会放回第一个括号捕获的内容。第二个括号对应 $2,依次类推。
[\s\S]*? 可以读取包含换行的内容,并在遇到最近的 </status> 时停止。它适合约定明确的简单标签,不适合解析任意嵌套 HTML。
怎样测试
至少准备四种输入:
| 输入 | 预期结果 |
|---|---|
<status>地点:玻璃温室</status> | 正常生成状态卡 |
| 普通回复,没有状态标签 | 原文保持不变 |
| 一条消息包含两个状态标签 | 两处都被替换 |
| 标签内容中有换行 | 换行内容仍在卡片中 |
正则测试面板使用浏览器 JavaScript 执行替换。测试通过后,再到聊天预览检查 HTML 和 CSS 的真实效果。
保存成功不等于正则有效
当前角色卡保存会整理正则格式和顺序,但不会在这条保存路径上完成全部 RE2 语法及 flags 校验。编辑器提示、保存结果、浏览器显示和服务端独立测试是四项不同检查。
常见问题
完全匹配不到
先复制一段真实角色回复,不要凭记忆重写。检查标签、空格、全角标点和大小写是否一致。
只替换第一处
确认 flags 包含 g。它表示在 JavaScript 显示路径中替换所有匹配。
$1 显示为空
确认查找表达式中真的有一组括号,并且括号包住了需要保留的内容。
替换后只有 HTML 文字
先确认替换结果是完整标签,再检查对应环境是否允许该消息进入 HTML 渲染路径。复杂 HTML 和角色自定义标签在流式回复期间可能延后展示,应在回复结束后检查。
应用于哪个位置
| 编辑器选项 | placement | 用途 |
|---|---|---|
| 用户消息 | 0 | 处理用户发送的文字 |
| AI 消息 | 1 | 处理角色回复和相应开场白展示 |
| 斜杠命令 | 2 | 处理斜杠命令位置的内容 |
新规则默认用于 AI 消息。选择“斜杠命令”只设置规则位置,不会创建命令,也不保证每个宿主都有命令入口。
多条规则按列表顺序执行,上一条结果会交给下一条。禁用规则不会运行。历史导入数据没有 placement 时,部分运行时可能兼容到所有消息,新规则应明确选择位置。
flags 怎么选
| flag | 用途 | 建议 |
|---|---|---|
g | 替换所有匹配 | 多数展示规则需要 |
i | 忽略大小写 | 标签大小写可能变化时使用 |
m | ^、$ 按行匹配 | 只有按行定位时使用 |
s | . 可以匹配换行 | 可用 [\s\S] 获得更清楚的跨端含义 |
u | JavaScript Unicode 模式 | 服务端不会因此切换成完整 JS 语义 |
y | JavaScript sticky 模式 | 不建议用于跨端规则 |
编辑器和独立正则接口按 gimsuy 检查 flags,并提示重复字符。新规则直接填写独立 flags,不要把 (?i)、(?m)、(?s) 当作首选写法。
需要避开的写法
如果规则还需要经过独立正则接口或服务端测试,应兼容 Go regexp / RE2。以下语法会被相应校验路径拒绝:
- lookahead:
(?=...)、(?!...) - lookbehind:
(?<=...)、(?<!...) - 查找表达式中的反向引用:
\1 - 带作用域的内联 flags:
(?i:...)
查找表达式中的 \1 与替换模板中的 $1 不同。跨端规则推荐使用简单编号捕获组,并把 $1 放在替换模板中。
显示替换与消息保存不是一回事
Creator、Web 和 App 的显示路径使用各自 JavaScript 环境执行正则。无法编译的规则会被跳过。显示替换不会自动证明服务器中的原消息已经改写。
如果确实需要修改已保存消息,阅读 onTransformMessage 的保存边界。不要用一张成功的预览图推定三个环境都已通过。
保存前检查
- 原始回复确实包含约定标签。
- 正常、不匹配、多匹配和换行输入都已测试。
- 捕获组与
$1、$2的位置一致。 - flags 没有重复,只包含实际需要的字符。
- Creator 预览中的完整回复显示正确。
- 目标 Web、App 环境已经分别检查。
下一步:为状态卡添加 CSS,或直接查看完整实例。