一、前言
在日常 Oracle 数据库运维、HIS / 医保系统数据治理、脏数据清洗场景中,普通 LIKE、REPLACE、INSTR 函数面对不规则空白、特殊字符、混合文本、格式校验等场景往往力不从心。
Oracle 10g 及以上版本全面支持 POSIX 标准正则表达式,提供 5 大核心正则函数,非常适合医疗行业海量基础数据清洗、格式校验、字符串拆分、内容替换等工作。
本文结合医院业务真实场景,整理正则基础语法、5 大核心函数、高频实战案例、踩坑避坑点,可直接复制落地使用。
适用场景:HIS 系统药品名称、诊疗项目、编号、地址、备注等字段脏数据清洗、格式校验、违规字符过滤。
二、前置说明 & 基础元字符
2.1 重要规则
-
Oracle 正则默认区分大小写 ,可通过匹配模式
i忽略大小写; -
不推荐使用
\d、\s、\w等简写(低版本兼容差),优先使用字符集写法; -
空白字符分为标准空白 (空格、Tab、回车、换行)和全角空格,二者需分开处理;
-
编辑器会对动态拼接正则产生语法误报,以数据库实际执行结果为准。
2.2 常用基础元字符
|-------------------|----------------------------|
| 元字符 | 说明 |
| ^ | 匹配字符串开头 |
| $ | 匹配字符串结尾 |
| . | 匹配任意单个字符(默认不匹配换行) |
| + | 前面字符至少出现 1 次 |
| * | 前面字符出现 0 次或多次 |
| [] | 字符集,匹配括号内任意一个字符 |
| [^] | 取反,匹配不在括号内的字符 |
| [\u4e00-\u9fff] | 匹配汉字(Oracle 11gR2+ 推荐) |
| [[:space:]] | POSIX 标准空白:半角空格、Tab、回车、换行 |
三、Oracle 五大正则核心函数总览
Oracle 正则家族共 5 个高频函数,覆盖判断、替换、截取、定位、统计全场景:
|------------------|--------------------|---------------------------|
| 函数 | 核心作用 | 典型业务场景 |
| REGEXP_LIKE | 正则匹配判断(WHERE 条件筛选) | 脏数据筛查、格式校验、判断是否含汉字 / 特殊字符 |
| REGEXP_REPLACE | 正则全局替换 | 清除空白、过滤特殊字符、数据脱敏、脏字符清洗 |
| REGEXP_SUBSTR | 正则截取子串 | 拆分逗号分隔字符串、提取数字 / 编号 |
| REGEXP_INSTR | 获取匹配内容位置 | 定位特殊字符、非法字符下标 |
| REGEXP_COUNT | 统计匹配次数 | 统计符号、汉字、关键字出现次数 |
通用语法格式:
REGEXP_XXX(源字符串, 正则表达式 [, 起始位置] [, 匹配序号] [, 匹配模式])
匹配模式:
-
c:区分大小写(默认) -
i:忽略大小写 -
m:多行模式
四、函数详解 + 实战案例(可直接运行)
4.1 REGEXP_LIKE 正则匹配判断
作用 :用于 WHERE 条件,筛选符合 / 不符合正则规则的数据,数据排查最常用。
案例 1:查询字段包含汉字的记录
-- 药品名称、项目名称包含汉字(通用标准写法) SELECT * FROM gy_zt02 t WHERE REGEXP_LIKE(t.xmmc, '[\u4e00-\u9fff]');
案例 2:查询纯数字数据(校验编号、金额、数量字段)
-- 整行内容为纯数字 SELECT * FROM gy_zt02 t WHERE REGEXP_LIKE(t.gytj, '^[0-9]+$');
案例 3:查询非纯数字脏数据(重点排查)
-- 找出包含字母、符号、汉字、空格的异常数据 SELECT * FROM gy_zt02 t WHERE NOT REGEXP_LIKE(t.gytj, '^[0-9]+$') AND t.gytj IS NOT NULL;
案例 4:查询包含标准空白(空格 / Tab / 回车 / 换行)的数据
SELECT * FROM gy_ylml l WHERE REGEXP_LIKE(l.dwqc, '[[:space:]]');
案例 5:查询包含字母的数据
SELECT * FROM gy_zt02 t WHERE REGEXP_LIKE(t.xmmc, '[A-Za-z]');
4.2 REGEXP_REPLACE 正则替换(数据清洗核心)
作用:全局匹配字符并替换,清洗各类隐形脏字符、多余空格、特殊符号。
案例 1:清除所有标准空白(空格、Tab、回车、换行)
-- 更新语句:清除字段内全部标准空白 UPDATE gy_ylml l SET l.dwqc = REGEXP_REPLACE(l.dwqc, '[[:space:]]', '') WHERE REGEXP_LIKE(l.dwqc, '[[:space:]]');
案例 2:单独清除全角空格(高频坑点)
[[:space:]] 无法匹配全角空格 ,使用普通 REPLACE 处理:
-- 清除全角空格 CHR(12288) UPDATE gy_ylml l SET l.dwqc = REPLACE(l.dwqc, CHR(12288), '') WHERE INSTR(l.dwqc, CHR(12288)) > 0;
案例 3:清除所有非数字字符(仅保留数字)
适用于金额、数量、流水号字段清洗:
SELECT gytj AS 原始值, REGEXP_REPLACE(gytj, '[^0-9]', '') AS 清洗后纯数字 FROM gy_zt02;
案例 4:清除数字、汉字以外的所有特殊符号
SELECT xmmc AS 原始名称, REGEXP_REPLACE(xmmc, '[^0-9\u4e00-\u9fff]', '') AS 清洗后名称 FROM gy_zt02;
案例 5:手机号简单脱敏(中间 4 位打码)
SELECT REGEXP_REPLACE('13800138000','(^1[0-9]{3})([0-9]{4})([0-9]{4})$','\1****\3') AS 脱敏手机号 FROM DUAL;
4.3 REGEXP_SUBSTR 正则截取子串
作用:按规则提取字符串片段、拆分分隔符文本。
案例 1:提取字符串中的纯数字
SELECT REGEXP_SUBSTR('编号:A123456测试', '[0-9]+') AS 提取数字 FROM DUAL;
案例 2:逗号分隔字符串 行转列(经典用法)
-- 将 1,2,3,4 拆分为多行数据 SELECT REGEXP_SUBSTR('苹果,香蕉,橘子,葡萄', '[^,]+', 1, LEVEL) AS 拆分结果 FROM DUAL CONNECT BY LEVEL <= REGEXP_COUNT('苹果,香蕉,橘子,葡萄', ',') + 1;
4.4 REGEXP_INSTR 匹配位置查询
作用:返回匹配字符在字符串中的下标,找不到返回 0。
案例:查询第一个数字出现的位置
SELECT REGEXP_INSTR('ABCDE12345', '[0-9]') AS 数字起始位置 FROM DUAL;
4.5 REGEXP_COUNT 统计匹配次数
作用:统计指定字符 / 规则在字符串中出现的次数。
案例 1:统计逗号个数
SELECT REGEXP_COUNT('101,102,103,104', ',') AS 逗号数量 FROM DUAL;
案例 2:统计字符串中汉字数量
SELECT REGEXP_COUNT('测试数据123ABC', '[\u4e00-\u9fff]') AS 汉字个数 FROM DUAL;
五、综合实战:医疗系统脏数据完整清洗流程
针对 gy_ylml、gy_zt02 这类基础表,一套标准清洗流程(先查询预览,再执行更新)。
步骤 1:预览所有含空白的脏数据(安全校验)
SELECT dwqc AS 原始内容, REGEXP_REPLACE(dwqc, '[[:space:]]', '') AS 清标准空白, REPLACE(dwqc, CHR(12288), '') AS 清全角空格 FROM gy_ylml WHERE REGEXP_LIKE(dwqc, '[[:space:]]') OR INSTR(dwqc, CHR(12288)) > 0;
步骤 2:分步执行清洗(规避正则拼接报错)
-- 第一步:清除标准空白(空格、Tab、回车、换行) UPDATE gy_ylml l SET l.dwqc = REGEXP_REPLACE(l.dwqc, '[[:space:]]', '') WHERE REGEXP_LIKE(l.dwqc, '[[:space:]]'); -- 第二步:清除全角空格 UPDATE gy_ylml l SET l.dwqc = REPLACE(l.dwqc, CHR(12288), '') WHERE INSTR(l.dwqc, CHR(12288)) > 0;
步骤 3:校验清洗结果
-- 清洗后,查询是否还存在空白字符 SELECT * FROM gy_ylml l WHERE REGEXP_LIKE(l.dwqc, '[[:space:]]') OR INSTR(l.dwqc, CHR(12288)) > 0;
六、高频踩坑点 & 避坑总结
-
[[:space:]]不匹配全角空格 全角空格CHR(12288)必须单独用REPLACE处理,不要强行正则拼接,易报ORA-12726方括号不匹配。 -
禁止在 Oracle 使用
\w、\d、\s低版本 Oracle 不兼容,\w会被识别为普通字母w,统一替换:-
\d→[0-9] -
\w→[A-Za-z0-9_] -
\s→[[:space:]]
-
-
正则拼接字符串编辑器误报
'['||CHR()||'-'||CHR()||']'语法本身合法,多数是客户端编辑器语法检查异常,优先使用[\u4e00-\u9fff]汉字写法。 -
TRIM函数局限性 原生TRIM仅能清除首尾半角空格,无法处理中间空格、Tab、全角空格、换行,复杂空白必须用正则。 -
执行 UPDATE 前务必 SELECT 预览 数据清洗属于高危操作,先查询查看效果,再执行更新,避免批量误改业务数据。
七、常用正则速查表(日常直接复制)
-- 1. 判断包含汉字 REGEXP_LIKE(字段, '[\u4e00-\u9fff]') -- 2. 判断纯数字 REGEXP_LIKE(字段, '^[0-9]+$') -- 3. 判断含标准空白 REGEXP_LIKE(字段, '[[:space:]]') -- 4. 清除所有标准空白 REGEXP_REPLACE(字段, '[[:space:]]', '') -- 5. 清除全角空格 REPLACE(字段, CHR(12288), '') -- 6. 只保留数字,清除其余所有字符 REGEXP_REPLACE(字段, '[^0-9]', '')
标签:#Oracle #正则表达式 #数据清洗 #HIS 系统 #数据库运维 #脏数据处理