Oracle中使用regexp_like匹配指定规则中文字符串无返回结果如何解决
问题原因
两个SQL无法命中结果的原因如下:
- 第二段SQL的
[\u4e00-\u9fa5]写法不兼容Oracle正则规则:\u开头的Unicode转义是Java、Python等编程语言的正则语法,Oracle正则解析器不识别该写法,会把\u4e00按普通字符序列(反斜杠、u、4、e、0、0)匹配,完全无法命中中文。 - 第一段SQL的unistr拼接写法在纯半角符号、二进制排序规则下理论可运行,失效基本是以下三类问题:
- 排序规则干扰:中文环境下Oracle默认
NLS_SORT参数通常设为拼音/笔画/部首排序,而非二进制排序,此时你写的[一-龥]范围不会按Unicode编码判定,会出现大量中文漏匹配的情况。 - 符号不匹配:正则中
\.仅匹配半角英文句号,如果字段里存的是中文全角句号.,或者点号前后、字段首尾存在不可见空白(空格、全角空格、换行符等),会直接导致匹配失败。 - 样例中
德州分公司.综合部、德州分公司.集团客户部两个值结尾不是“公司”,本身就不符合匹配规则,不返回是正常结果。
- 排序规则干扰:中文环境下Oracle默认
可用写法
无严格中文校验需求(最稳妥)
如果只需要匹配“德州分公司.开头、公司结尾”的规则,不需要强制校验中间字符全为中文,直接用通配符即可,兼容性最好:
SELECT * FROM SF_GROUP T -- TRIM去掉首尾空白干扰,[..]同时兼容半角、全角句号 WHERE REGEXP_LIKE(TRIM(T.GROUP_NAME), '^德州分公司[..].*公司$');
需要严格限定中间为中文
Oracle 11gR2及以上版本支持POSIX中文字符类,不需要手动拼接汉字范围,不受排序规则影响:
SELECT * FROM SF_GROUP T WHERE REGEXP_LIKE(TRIM(T.GROUP_NAME), '^德州分公司[..][[:hanzi:]]*公司$');
如果是低版本Oracle不支持上述字符类,可以在你原有写法基础上加上二进制匹配参数,规避排序规则干扰:
SELECT * FROM SF_GROUP T WHERE REGEXP_LIKE(TRIM(T.GROUP_NAME), '^德州分公司[..][' || UNISTR('\4e00') || '-' || UNISTR('\9fa5') || ']*公司$', 'c'); -- 传入'c'参数强制按二进制编码匹配,忽略NLS排序规则影响
排查技巧
如果上述写法还是无法命中,可以先执行以下SQL查看字段实际存储的字节内容,确认是否存在不可见字符、符号类型不符的问题:
SELECT GROUP_NAME, DUMP(GROUP_NAME,16) FROM SF_GROUP WHERE GROUP_NAME LIKE '德州分公司%' AND ROWNUM <= 20;
如果返回结果中“德州分公司”后的点字节值不是2e(半角句号)或a3ae(全角句号),说明字段里存在其他特殊字符,对应调整正则即可。
内容的提问来源于stack exchange,提问作者Michael
相关产品推荐
相关产品推荐

