WPS 里用正则表达式,最常见的现象就是“同一个表达式,换个地方就不生效”。在文档查找替换里写得好好的,粘到 VBA 宏里报错;VBA 里能跑,扔到 JSA 里结果又不一样。原因并不复杂:WPS 并没有把正则表达式统一交给同一个引擎去解析,而是根据你操作的位置,分别调用了三套不同规则的正则引擎。这套差异如果没搞清楚,排查起来会非常耗时。
这篇文章就把 WPS 里最常见的三种正则引擎拆开讲清楚:第一,WPS 文字/表格“查找与替换”对话框里的通配符引擎;第二,VBA 宏里通过CreateObject("VBScript.RegExp")调用的 VBScript 正则引擎;第三,WPS 主推的 JSA(JavaScript for Automation)宏里使用的 JavaScript RegExp 引擎。看完你会知道每个引擎支持什么、不支持什么、表达式的写法有哪些坑,以及如何在本地快速验证。内容不依赖某个具体 WPS 版本,但会用当前主流的 WPS 版本习惯来说明,菜单文字如果和你本机不一样,以实际版本为准。
1. 核心能力速览
在正式开始之前,先把三种正则引擎的定位、入口、特点和限制收在一张表里。后面章节再逐个展开细节。
| 引擎/入口 | 出现位置 | 语法基础 | 适用人群 | 主要限制 |
|---|---|---|---|---|
| 查找替换通配符引擎 | WPS 文字的“查找和替换”对话框,勾选“使用通配符” | Word 兼容通配符语法,是正则的裁剪版 | 手工处理文档、做一次性替换 | 不支持\d、\w等简写,语法最弱;替换时使用\1引用分组 |
| VBA RegExp 对象 | WPS 开发工具 → VB 编辑器,宏代码 | VBScript.RegExp 5.5 级别引擎 | 从 Excel/VBA 迁移过来的老项目 | 不支持后顾断言,Unicode 处理较弱,需要写 VBA 代码 |
| JSA RegExp 对象 | WPS 开发工具 → JS 宏 | JavaScript RegExp,由 WPS 内嵌 JS 引擎执行 | 新项目、批量处理、模板化脚本 | JS 引擎版本随 WPS 版本变化,正则新特性支持程度不一致 |
三种引擎的能力定位很清晰:
- 查找替换通配符引擎最直观,适合在界面上手工处理少量文本,但它在语法上做了大量裁剪,很多正则中常见的缩写都不认识。
- VBA RegExp 引擎是许多老用户熟悉的方案,兼容性好,适合把 Excel/VBA 时代的脚本迁移到 WPS,但它的语法能力停留在较早的 VBScript 正则版本,
(?<=)这类写法直接用不了。 - JSA RegExp 引擎是目前 WPS 主推的宏方案,语法接近现代 JavaScript,批量处理和接口封装更灵活,前提是你的 WPS 版本内置的 JS 引擎要够新。
从工程角度选型,可以按这个简单原则:手动替换用查找替换通配符;存量宏用 VBA;新写的批量脚本优先用 JSA。
2. 适用场景与使用边界
2.1 适合谁用
如果你的工作流里有这些诉求,这篇文章涉及的三个引擎会非常实用:
| 使用场景 | 推荐引擎 |
|---|---|
手工把文档中的日期格式从2024-01-15改成2024/01/15 | 查找替换通配符 |
| 批量提取多列手机号、邮箱、金额信息 | JSA 或 VBA |
| 把 Excel 老宏迁移到 WPS | VBA RegExp |
| 需要写成自动化脚本,由同事或非技术用户运行 | JSA |
| 不想写代码,只想快速统计某类字符出现次数 | 查找替换通配符 |
2.2 不适合什么场景
- 查找替换通配符引擎不适合处理复杂条件、多步骤逻辑、跨文档批量任务,它的定位是“界面里的轻量操作”,而不是程序设计接口。
- VBA RegExp 不适合需要处理复杂 Unicode、需要后顾断言、需要命名捕获组的高阶正则需求。
- JSA RegExp 如果用在较旧版本的 WPS 上,ES6 之后新增的正则特性不一定可用,写之前要做能力探测。
2.3 合规与安全边界
正则表达式本身是高效率的文本处理工具,但使用它处理手机号、身份证号、银行卡号、工资字段等个人和商业敏感数据时,一定要把握边界:
- 不要在日志、调试输出里打印完整的敏感数据。
- 批量替换和提取完成后,如果数据不再需要,要及时清理中间文件。
- 涉及他人数据时,确保有合法处理依据,不要因为“正则只是匹配文本”就忽略隐私和版权合规。
- 如果正则表达式来自网络或第三方,先审查它是否存在恶意行为,尤其是用于读取文件、执行命令的上下文里,避免被注入式利用。
3. 第一种引擎:查找替换通配符引擎
3.1 入口和触发方式
在 WPS 文字中打开“查找和替换”对话框,一般快捷键是Ctrl+H。在“查找内容”或“替换为”输入框附近找到“高级”或“选项”区域,勾选“使用通配符”。勾选之后,你在输入框里输入的很多字符就会被当成特殊符号解析,而不是普通文本。
在 WPS 表格中,查找和替换对话框通常也有类似选项,但表格里的通配符能力通常比文字里更弱,很多版本只支持*、?、~三个基础通配符。实际使用时需要注意区分:
- WPS 文字:功能相对完整,接近 Word 的通配符。
- WPS 表格:通常只是“通配符”,不是完整正则。
如果你想在表格里按正则规则提取数据,跨过查找替换,直接使用 VBA/JSA 宏更可靠。
3.2 语法特点
这个引擎可以理解成“正则表达式的裁剪版”。它保留了替换场景中最常用的一组能力,同时砍掉了正则里大量专业符号。
常用写法:
| 含义 | 通配符写法 | 对应正则写法 |
|---|---|---|
| 任意单个字符 | ? | . |
| 任意字符串 | * | .* |
| 指定字符集合 | [abc] | [abc] |
| 指定范围 | [a-z] | [a-z] |
| 排除字符 | [!a-z] | [^a-z] |
| 出现 n 次 | {n} | {n} |
| 出现至少 n 次 | {n,} | {n,} |
| 出现 n 到 m 次 | {n,m} | {n,m} |
| 分组 | () | () |
| 分组引用(替换时) | \1 | $1 |
这个列表已经很能说明问题:查找替换通配符引擎里,\d、\w、\s这些常用简写并不被普遍支持。要匹配数字,你得老老实实地写[0-9];要匹配字母,写[a-z]。
3.3 操作示例
假设 WPS 文字里有一段文本:
订单 2024-01-15 已发货,补货 2025-06-20 到达。如果想把日期中的-统一替换为/,步骤为:
- 按
Ctrl+H打开替换。 - 点击“高级/选项”,勾选“使用通配符”。
- 在“查找内容”输入:
([0-9]{4})-([0-9]{2})-([0-9]{2}) - 在“替换为”输入:
\1/\2/\3 - 点击“全部替换”。
判断成功的标准是:日期内容没有变化,只是连接符被替换成了/。如果直接写\d{4}-\d{2}-\d{2},在这一步很可能什么都匹配不到,因为通配符引擎不认识\d。
3.4 使用注意事项
- 勾选“使用通配符”后,
*、?不再表示普通字符。要查找星号本身,需要转义:\*。 - 替换时引用分组,用的是
\1而不是$1。这一点和正则习惯刚好相反,容易踩坑。 - 查找时分组是否支持反向引用,不同 WPS 版本表现不完全一致,不要依赖它做复杂递归匹配。
*的行为和正则里的.*不完全一样,正则里的*是修饰前一个字符的,而通配符里的*本身就代表一段字符。如果你带着正则思路去写ab*,在通配符引擎里会理解成“以 a 开头,以 b 结尾的任意内容”,而不是“a 后面有零个或多个 b”。
4. 第二种引擎:VBA RegExp 对象
4.1 入口和环境
WPS 的 VBA 环境通过“开发工具”选项卡进入。如果你的 WPS 界面上看不到“开发工具”,先到“文件 → 选项”或“设置”里把“开发工具”选项卡开启。
VBA 里使用正则,通常不是直接写New RegExp,而是通过:
Set reg = CreateObject("VBScript.RegExp")这种方式创建的正则对象,底层是 VBScript 正则引擎。它的能力介于传统正则和现代正则之间,使用门槛低,兼容性也不错。
4.2 核心属性和方法
VBA RegExp 对象有四个核心属性和三个方法:
| 成员 | 作用 |
|---|---|
Pattern | 设置正则表达式,比如\d{4}-\d{2}-\d{2} |
Global | 是否全局匹配。设置为True,否则默认只返回第一个匹配 |
IgnoreCase | 是否忽略大小写 |
MultiLine | 是否按多行模式处理^和$ |
Test方法 | 判断文本是否符合模式,返回布尔值 |
Execute方法 | 返回匹配集合,可遍历取出每一个匹配结果 |
Replace方法 | 按正则替换文本,替换引用使用$1 |
4.3 可用的正则语法
VBA RegExp 支持的语法包括:
.匹配除换行符外的任意字符*、+、?量词{n}、{n,}、{n,m}次数限定[...]、[^...]字符集合\d、\D、\w、\W、\s、\S简写\b词边界^、$行首行尾()捕获组、(?:...)非捕获组(?=...)正向前瞻、(?!...)负向前瞻|分支
关键的限制是:不支持(?<=...)后顾断言,不支持(?<!...)反向否定后顾,不支持命名捕获组(?<name>...),也不支持 Unicode 属性转义。如果你在网上看到一段现代正则里包含(?<=)的代码,直接粘到 VBA 里很大概率报错。
4.4 示例:从 WPS 表格中提取日期
下面的代码演示从 A1:A100 的每个单元格文本中提取所有日期,输出到 B 列:
Sub ExtractDateFromColumn() Dim reg As Object Set reg = CreateObject("VBScript.RegExp") reg.Pattern = "\d{4}-\d{1,2}-\d{1,2}" reg.Global = True Dim cell As Range Dim m As Variant Dim output As String For Each cell In ActiveSheet.Range("A1:A100") If Len(cell.Value) > 0 Then output = "" For Each m In reg.Execute(cell.Value) output = output & m.Value & vbCrLf Next cell.Offset(0, 1).Value = Trim(output) End If Next End Sub这段代码里没有使用后顾断言,也没有使用$1替换,所以 VBScript 正则引擎可以稳定处理。如果你把reg.Global从代码里删掉,那么每个单元格里的多个日期就只能提取出第一个,这是非常常见的问题。
4.5 示例:替换并打码手机号
VBA RegExp 的 Replace 方法,替换中引用分组使用$1,注意不是\1:
Sub MaskPhone() Dim reg As Object Set reg = CreateObject("VBScript.RegExp") reg.Pattern = "(1[3-9]\d)\d{4}(\d{4})" reg.Global = True Dim s As String s = "张三 13812345678,李四 15987654321" s = reg.Replace(s, "$1****$2") Debug.Print s End Sub输出:
张三 138****5678,李四 159****4321这段代码使用了(1[3-9]\d)捕获手机号前三位数字,(\d{4})捕获最后四位数字,中间四位替换为*。替换串里写的是$1****$2,不是\1****\2。这个差异非常容易踩坑,尤其是从其他语言转到 VBA 时。
5. 第三种引擎:JSA RegExp 对象
5.1 入口和环境
JSA 是 WPS 提供的 JavaScript 宏方案。进入方式通常是:
- 打开 WPS,进入“开发工具”选项卡。
- 点击“JS 宏”。
- 在弹出的代码编辑器里新建模块,写 JavaScript 函数。
JSA 里的正则表达式使用 JavaScript RegExp 对象,支持两种写法:
// 字面量写法 var re = /\d{4}-\d{1,2}-\d{1,2}/g; // 构造函数写法 var re = new RegExp("\\d{4}-\\d{1,2}-\\d{1,2}", "g");两种写法的区别重点在转义上。字面量写法里写\d就行,构造函数写法里因为字符串本身也要转义,所以必须写成"\\d"。很多从 VBA 转到 JSA 的人,经常在这一步出问题。
5.2 常用方法和属性
JavaScript RegExp 对象的能力以 ECMAScript 规范为基准,常用的方法有:
| 方法/属性 | 作用 |
|---|---|
test() | 测试是否匹配,返回布尔值 |
exec() | 返回第一个匹配,以及捕获组信息 |
String.match() | 在字符串上执行匹配,带g时返回所有匹配 |
String.replace() | 正则替换,替换串中使用$1 |
String.replaceAll() | 全局替换,视引擎版本支持 |
IgnoreCase | 对应修饰符i |
| 全局匹配 | 对应修饰符g |
| 多行匹配 | 对应修饰符m |
| dotAll | 对应修饰符s,视引擎版本支持 |
5.3 JSA 正则示例
下面这段代码演示了在 JSA 中提取文本里所有日期的用法:
function extractDatesWithJSA() { let text = "2024-01-15 下单,2025-06-20 发货"; let re = /\d{4}-\d{1,2}-\d{1,2}/g; let result = text.match(re); if (result) { console.log(result.join("\n")); } }如果你要在当前工作表里处理单元格数据,可以写成:
function extractDatesFromRange() { let re = /\d{4}-\d{1,2}-\d{1,2}/g; for (let i = 1; i <= 100; i++) { let cell = ActiveSheet.Cells.Item(i, 1); let val = cell.Value2; if (val) { let matches = String(val).match(re); if (matches) { ActiveSheet.Cells.Item(i, 2).Value2 = matches.join(";"); } } } }这段代码里用到了ActiveSheet.Cells.Item(i, 1),这是 WPS JSA 操作单元格的常见接口。不同版本对对象模型接口的支持有细微差异,如果有方法不存在,用下拉提示查看实际接口名称即可。
5.4 JSA 正则使用注意事项
$1在String.replace()中表示第一个捕获组,这一点和 VBA RegExp 的 Replace 方法一致,但和 WPS 查找替换通配符里的\1不同。- 构造函数
new RegExp("\\d")容易出现转义问题,调试时可先用console.log打印正则源码,确认没有变成new RegExp("\d")。 - 如果你依赖
(?<=name)这类后顾断言、命名捕获组,一定要先在当前 WPS 版本上做小样本测试。WPS 内置 JS 引擎版本会影响这些新特性的支持情况,不能只看网上的 JavaScript 教程就说一定支持。 \w默认匹配[A-Za-z0-9_],不能直接匹配中文。要匹配中文字符,需要写[\u4e00-\u9fa5]或根据实际字符范围调整。
6. 三种引擎的语法差异对照
把三种引擎放在一张表里对比,能更快看出同一个功能在不同入口下的写法区别:
| 功能 | 查找替换通配符 | VBA RegExp | JSA RegExp |
|---|---|---|---|
| 任意单个字符 | ? | . | . |
| 任意字符串 | * | .* | .* |
| 数字字符 | [0-9] | \d | \d |
| 字母数字下划线 | [a-zA-Z0-9_] | \w | \w |
| 空白字符 | 无直接简写 | \s | \s |
| 单词边界 | \<和\>,需验证 | \b | \b |
| 出现次数 | {n,m} | {n,m} | {n,m} |
| 分组 | () | () | () |
| 分组引用(替换时) | \1 | $1 | $1 |
| 非贪婪匹配 | 有限支持,需测试 | *? | *? |
| 正向前瞻 | 不支持 | (?=...) | (?=...) |
| 负向前瞻 | 不支持 | (?!...) | (?!...) |
| 后顾断言 | 不支持 | 不支持 | 视版本 |
| 命名捕获组 | 不支持 | 不支持 | 视版本 |
| 忽略大小写 | 界面勾选 | IgnoreCase=True | 修饰符i |
| 全局匹配 | 默认查找全部 | Global=True | 修饰符g |
表格里的“视版本”表示需要以你本机 WPS 的实际表现和内置 JS 引擎能力为准。不要因为网上说某个新特性可用,就直接拿到生产脚本里使用,先跑最小用例验证。
7. 同一段测试文本,三种引擎各跑一遍
为了上手更快,建议你建立一份标准测试文本,包含日期、数字、金额、手机号、英文单词等元素。以后无论切换到哪个引擎,都能用同一份数据判断语法支持情况。
测试文本示例:
2024-01-15 客户 A 下单,金额 1,234.56,电话 13812345678; 2025-06-20 客户 B 补单,金额 9,876.50,电话 15987654321。目标:提取所有2024-01-15格式的日期。
7.1 查找替换通配符引擎验证
- 把测试文本复制到 WPS 文字中。
- 按
Ctrl+H打开替换。 - 勾选“使用通配符”。
- 查找内容输入:
[0-9]{4}-[0-9]{2}-[0-9]{2} - 点击“查找下一处”,观察是否依次找到两个日期。
预期结果:两处日期都能高亮。如果什么也找不到,优先检查“使用通配符”是否勾选,以及是不是误用了\d简写。
如果要在替换中保留原日期并加前缀,可以修改为:
- 查找内容:
([0-9]{4}-[0-9]{2}-[0-9]{2}) - 替换为:
日期:\1
注意这里的分组不是必须做无限嵌套,而是为了在替换内容中引用它。
7.2 VBA RegExp 引擎验证
在 VBA 编辑器中新建模块,写入:
Sub TestVBARegex() Dim s As String s = "2024-01-15 客户 A 下单,金额 1,234.56,电话 13812345678;" & vbCrLf & _ "2025-06-20 客户 B 补单,金额 9,876.50,电话 15987654321。" Dim reg As Object Set reg = CreateObject("VBScript.RegExp") reg.Pattern = "\d{4}-\d{1,2}-\d{1,2}" reg.Global = True Dim m As Variant For Each m In reg.Execute(s) Debug.Print m.Value Next End Sub运行后在“立即窗口”可见:
2024-01-15 2025-06-20如果在 VBA 里第一个日期都能匹配到,但第二个没有,说明Global没有设置为True。
7.3 JSA RegExp 引擎验证
在 JS 宏编辑器中写入:
function testJSARegExp() { let text = "2024-01-15 客户 A 下单,金额 1,234.56,电话 13812345678;\n" + "2025-06-20 客户 B 补单,金额 9,876.50,电话 15987654321。"; let re = /\d{4}-\d{1,2}-\d{1,2}/g; let result = text.match(re); console.log(result ? result.join("\n") : "无匹配"); }运行后控制台输出两行日期。这里如果漏掉g修饰符,match只返回第一个完整匹配,不会返回全部日期。
通过这三组实验,你能很直观地看到同一个正则目的,在不同引擎里的写法和需要注意的地方不同。建议把这组测试固定保存成模板,以后排查问题时直接复制粘贴。
8. 常见问题与排查方法
下面整理出一张排查表,基本覆盖 WPS 正则最常见的踩坑点:
| 问题现象 | 可能原因 | 排查方式 | 解决方案 |
|---|---|---|---|
查找替换里写\d无结果 | 通配符引擎不识别\d | 检查是否勾选“使用通配符” | 改用[0-9] |
查找*反而搜不到普通星号 | 通配符模式下*是特殊字符 | 确认查找内容 | 转义为\*,或关闭通配符 |
| VBA 正则只替换第一处结果 | Global未设置为True | 检查代码里的属性赋值 | 加上reg.Global = True |
VBA 替换结果出现$1字面量 | 替换串写法不被当前引擎解析 | 确认使用的是 Replace 方法 | 使用$1替换,而不是\1 |
JSA 中new RegExp("\d+")异常 | 字符串转义导致正则在运行时变成d+ | 先console.log(reg)打印 | 改成new RegExp("\\d+")或使用字面量/\d+/ |
(?<=...)在 VBA 中报错 | VBScript 正则不支持后顾断言 | 检查报错位置 | 改用捕获组手动处理前缀 |
\w匹配不到中文 | \w默认是[A-Za-z0-9_] | 检查匹配结果 | 使用[\u4e00-\u9fa5]或显式字符范围 |
| JSA 使用新式正则特性无效果 | 内置 JS 引擎版本较旧 | 用最小用例测试 | 避开新特性,或用传统写法 |
| 宏运行被拦截 | WPS 宏安全设置 | 查看安全中心提示 | 在可信任环境中允许宏,或手动选择启用 |
| 批量处理卡住 | 正则回溯过多或循环范围过大 | 缩小范围,打印进度 | 优化正则,限制循环行数,增加超时退出 |
这些问题的共同点在于:大多数不是“正则不会写”,而是“引擎不匹配”。排查的时候先问自己三个问题:
- 你现在是在哪个入口执行?
- 这个入口用的引擎支持哪些语法?
- 当前 WPS 版本对这个引擎的实现有没有裁剪?
顺序对了,排查速度快很多。
9. 最佳实践与使用建议
9.1 按任务选择引擎
建议建立这样一个优先级习惯:
- 纯手工处理、不涉及代码逻辑,选 WPS 文字查找替换通配符。
- 需要遍历工作表中多行多列,并且希望用对象模型操作单元格,选 VBA 或 JSA。
- 存量项目是 VBA 写的,优先维护成 VBA,不要为了技术新鲜感强行迁移。
- 新项目、需要长期维护和扩展接口的,优先选 JSA,它的 JavaScript 语法对大多数开发者更友好。
9.2 保存最小可运行模板
把前面第 7 章的测试文本和三段脚本存成一个模板文件。以后遇到正则问题,先在这个模板里验证,不要直接在正式文档或正式数据上试。这个习惯能避免大量误操作。
模板里至少包含:
- 一段覆盖日期、手机号、金额、英文单词的测试文本。
- 查找替换通配符的验证步骤说明。
- VBA RegExp 的测试子过程。
- JSA RegExp 的测试函数。
9.3 写正则时注意边界数据
正则的难点通常不在正常文本,而在边界数据。测试时要覆盖:
- 空字符串。
- 全角空格、全角标点。
- 数字前后有字母或符号。
- 超长文本,比如 5000 字以上的段落。
- 同一行存在多个匹配。
- 中文和英文混排时
\w、\b的实际表现。
在不同引擎里,\w和\b对中文的支持程度不一致,尤其需要多测。
9.4 数据脱敏和合规
当你用正则提取手机号、身份证号、邮箱、金额等信息时,建议在代码中直接完成脱敏后再输出。不要在调试窗口打印完整手机号,不要在生产环境把带敏感信息的中间结果写进临时目录。处理完的数据如果不再需要,立即清理。
9.5 留意新版 WPS 的正则函数
如果你使用的是较新版本的 WPS 表格,可以优先查一下帮助文档里有没有以REGEX开头的函数,例如REGEXEXTRACT、REGEXREPLACE这类函数。不同版本对这类函数的开放程度和函数名可能不同。如果能用,它的最大优势是:不用写宏,直接在单元格里传参即可,适合快速处理和临时分析。但它本质上也是由 WPS 内置的正则能力封装,语法细节仍然要以官方帮助为准。
10. 总结与下一步
WPS 里的正则表达式并不是“一套规则走天下”,而是至少分成三条技术路线:查找替换通配符引擎、VBA RegExp 对象、JSA RegExp 对象。三者的能力、语法、适用场景差别很大。遇到“这个正则为什么在 WPS 里不生效”时,先判断自己用的是哪个入口,再对照对应的引擎语法,基本就能定位问题。
第一次使用建议先验证三件事:
- 当前 WPS 的查找替换对话框里,“使用通配符”选项在哪里,是否支持
[0-9]、{}、()、\1。 - VBA 里
CreateObject("VBScript.RegExp")能否正常创建,Global属性是否生效。 - JSA 里正则字面量
/\d+/g和构造函数new RegExp("\\d+", "g")是否都能正常运行。
这三项确认之后,就可以放心地把 WPS 的正则能力用到批量提取、批量替换、数据清洗和自动化脚本里。把这篇文章里的测试模板存下来,后续遇到任何引擎相关疑问,直接跑一遍模板,比反复查阅不可靠的碎片化教程要高效得多。