📋 目录
一、工具类功能
按正则提取首个或全部匹配、整体或指定捕获分组,再把 {key} 占位符渲染成参数值,无匹配给 null 或空列表,短信、站内信、通知模板这类文案拼装直接可用。
二、所需环境
JDK 17或以上
三、方法与调用示例(按需调用)
🔢 方法序号:1
🎯 方法用途:
- 取文本里第一个完整匹配的内容
- 日志里捞第一个订单号、回调报文里取第一个日期这类只要头一个的场景
🧩 方法定义:public static String extractFirst(String text, String regex)
🗣️ 入参解释:public static String extractFirst(文本, 正则)
📤 返回值解释:String,第一个匹配到的整段文本,没命中返回 null
💡 边界口径:
- 无匹配返回 null 而不是空串,调用方要判空
- 只给整体匹配,要分组内容用
extractGroup - 正则里有捕获组不影响本方法的返回
- 文本为 null、正则语法非法都抛
IllegalArgumentException,正则编译结果带缓存
🧪 方法示例:
extractFirst(callback, DATE)拿到2026-10-05extractFirst(callback, ORDER_NO)拿到ORD20261005000123- 文本里没有 SKU,
extractFirst(callback, "SKU[0-9]+")拿到null extractFirst(null, DATE)抛待匹配文本不能为nullextractFirst(callback, "([unclosed")抛正则表达式非法: Unclosed character class near index 9
🔢 方法序号:2
🎯 方法用途:
- 取第一个匹配里的指定捕获组,下标 0 是整体匹配
- 键值对、参数串这类「整体命中还要拆成几块」的场景用它
🧩 方法定义:public static String extractGroup(String text, String regex, int groupIndex)
🗣️ 入参解释:public static String extractGroup(文本, 正则, 分组下标)
📤 返回值解释:String,指定分组的内容,无匹配返回 null
💡 边界口径:
- 下标从 0 起,0 是整体匹配,1 起是第 1 个捕获组,负数抛异常
- 正则里没有这个分组直接抛异常,不静默给 null
- 无匹配时先返回 null,不再校验下标是否存在
- 分组存在但这次没参与匹配(可选分组没命中)时返回 null
🧪 方法示例:
extractGroup(callback, KEY_VALUE, 0)拿到amount=12800,是整体匹配extractGroup(callback, KEY_VALUE, 1)拿到amount,键名组extractGroup(callback, KEY_VALUE, 2)拿到12800,数值组extractGroup(callback, "sku=([0-9]+", 7)拿到null,没命中就不看下标extractGroup("b", "([a-z]+)([0-9])?", 2)拿到null,可选分组没参与匹配- 下标给 -1 抛
分组下标不能小于0,当前为-1 - 下标给 3 抛
正则中不存在下标为3的分组,当前分组数为2
🔢 方法序号:3
🎯 方法用途:
- 按出现顺序取文本里全部完整匹配
- 一条报文里多个订单号、一段文本里所有手机号这类批量提取用它
🧩 方法定义:public static List<String> extractAll(String text, String regex)
🗣️ 入参解释:public static List<String> extractAll(文本, 正则)
📤 返回值解释:List<String>,按出现顺序排列,无匹配是空列表
💡 边界口径:
- 不返回 null,可以直接遍历与判
isEmpty - 重复命中的内容会重复出现在列表里
- 能匹配空串的正则(如
x*)由Matcher.find()自行前移,返回若干空串但一定终止 - 文本为 null、正则非法都抛
IllegalArgumentException
🧪 方法示例:
extractAll(callback, ORDER_NO)拿到[ORD20261005000123, ORD20261005000456]- 一个都不命中时
extractAll(callback, "SKU[0-9]+")拿到[] extractAll("ab", "x*")拿到[, , ],三个空串但没死循环extractAll(null, "a")抛待匹配文本不能为null
🔢 方法序号:4
🎯 方法用途:
- 每次匹配都取同一个捕获组,把一组键或一组值单独捞出来
- 把
amount=12800&fee=80这类串拆成键列表、值列表时用这一版
🧩 方法定义:public static List<String> extractAllGroups(String text, String regex, int groupIndex)
🗣️ 入参解释:public static List<String> extractAllGroups(文本, 正则, 分组下标)
📤 返回值解释:List<String>,每次匹配该分组的内容,按出现顺序
💡 边界口径:
- 下标必须大于 0,整体匹配请用
extractAll,给 0 直接抛异常 - 分组没参与匹配时列表里放的是 null 元素,不是空串
- 无匹配返回空列表,不返回 null
- 分组不存在、正则非法同样抛
IllegalArgumentException
🧪 方法示例:
extractAllGroups(callback, KEY_VALUE, 1)拿到[amount, fee, currency],只取键名extractAllGroups(callback, KEY_VALUE, 2)拿到[12800, 80, 1],只取数值extractAllGroups("a1 b c2", "([a-z]+)([0-9])?", 2)拿到[1, null, 2],中间那次没命中的分组是 null- 下标给 0 抛
分组下标必须大于0,当前为0
🔢 方法序号:5
🎯 方法用途:
- 把模板里的
{key}换成参数表同名项的值,做短信、邮件这类文案渲染 - 参数缺失时宁可留原样也不要抛错的通知场景用它
🧩 方法定义:public static String render(String template, Map<String, ?> params)
🗣️ 入参解释:public static String render(模板, 参数表)
📤 返回值解释:String,替换后的文本
💡 边界口径:
- key 不存在或值为 null 时保留原占位符不替换,方便一眼看出漏传了哪个参数
- 替换值里的
$与反斜杠按字面量处理,不会走正则替换语法 - 替换值里再出现的
{key}不会被二次展开,避免循环替换 - 模板与参数表为 null 抛
IllegalArgumentException
🧪 方法示例:
render(message, params)拿到张三 您好,您尾款 128 元已于 {date} 到账,详情见 {empty},缺失的与 null 值的占位符原样留着- 替换值是
$1\2时拿到$1\2,符号没被当成正则替换语法 - 参数值里再套占位符时,
render("{a}", nested)拿到{b},不做二次展开 - 模板里一个占位符都没有时
render("", Map.of("name", "张三"))拿到[],括号里是空串结果 - 参数表传 null 抛
参数表不能为null - 模板传 null 抛
模板字符串不能为null
四、工具类源码(可直接复制)
📦 源码文件