Oracle 11g字符串精准提取优化方案求助
Oracle 11g精准提取7-12位字母数字子串的优化方案
需要从格式各异的Oracle 11g字符串中提取7-12位的字母数字组合子串,原方案依赖SUBSTR+INSTR+REGEXP_REPLACE基于第三个-分隔符截取,随着字符串格式复杂化(比如多分隔符、子串前后有特殊字符、子串位置变化等),现有逻辑无法适配,导致提取结果与预期不符。
原测试SQL
SELECT 'ABCD-012345-EFG-10vXRI47HU-1' AS MAIN_STRING, (TRIM(REGEXP_REPLACE(SUBSTR('ABCD-012345-EFG-10vXRI47HU-1',INSTR('ABCD-012345-EFG-10vXRI47HU-1','-',1,3)+1),'[^0-9A-Za-z]',''))) AS FUNCTION_OUTPUT, '10vXRI47HU' AS EXPECTED_OUTPUT FROM DUAL UNION ALL SELECT 'ABCD-012345-EFG-10zSD0U/2' AS MAIN_STRING, (TRIM(REGEXP_REPLACE(SUBSTR('ABCD-012345-EFG-10zSD0U/2',INSTR('ABCD-012345-EFG-10zSD0U/2','-',1,3)+1),'[^0-9A-Za-z]',''))) AS FUNCTION_OUTPUT, '10zSD0U' AS EXPECTED_OUTPUT FROM DUAL UNION ALL SELECT 'ABCD-012345-EFG-10ZsE8h -1' AS MAIN_STRING, (TRIM(REGEXP_REPLACE(SUBSTR('ABCD-012345-EFG-10ZsE8h -1',INSTR('ABCD-012345-EFG-10ZsE8h -1','-',1,3)+1),'[^0-9A-Za-z]',''))) AS FUNCTION_OUTPUT, '10ZsE8h' AS EXPECTED_OUTPUT FROM DUAL UNION ALL SELECT 'ABCD-012345-EFG- 10zSe9K ' AS MAIN_STRING, (TRIM(REGEXP_REPLACE(SUBSTR('ABCD-012345-EFG- 10zSe9K ',INSTR('ABCD-012345-EFG- 10zSe9K ','-',1,3)+1),'[^0-9A-Za-z]',''))) AS FUNCTION_OUTPUT, '10zSe9K' AS EXPECTED_OUTPUT FROM DUAL UNION ALL SELECT 'ABCD-012345-EFG-.10zSe9K' AS MAIN_STRING, (TRIM(REGEXP_REPLACE(SUBSTR('ABCD-012345-EFG-.10zSe9K',INSTR('ABCD-012345-EFG-.10zSe9K','-',1,3)+1),'[^0-9A-Za-z]',''))) AS FUNCTION_OUTPUT, '10zSe9K' AS EXPECTED_OUTPUT FROM DUAL UNION ALL SELECT 'ABCD-012345-EFG-10zSe9K_2' AS MAIN_STRING, (TRIM(REGEXP_REPLACE(SUBSTR('ABCD-012345-EFG-10zSe9K_2',INSTR('ABCD-012345-EFG-10zSe9K_2','-',1,3)+1),'[^0-9A-Za-z]',''))) AS FUNCTION_OUTPUT, '10zSe9K' AS EXPECTED_OUTPUT FROM DUAL UNION ALL SELECT 'ABCD-012345-EFG-10zSe9K.' AS MAIN_STRING, (TRIM(REGEXP_REPLACE(SUBSTR('ABCD-012345-EFG-10zSe9K.',INSTR('ABCD-012345-EFG-10zSe9K.','-',1,3)+1),'[^0-9A-Za-z]',''))) AS FUNCTION_OUTPUT, '10zSe9K' AS EXPECTED_OUTPUT FROM DUAL UNION ALL SELECT 'ABCD-012345--EFG-10zSe9K' AS MAIN_STRING, (TRIM(REGEXP_REPLACE(SUBSTR('ABCD-012345--EFG-10zSe9K',INSTR('ABCD-012345--EFG-10zSe9K','-',1,3)+1),'[^0-9A-Za-z]',''))) AS FUNCTION_OUTPUT, '10zSe9K' AS EXPECTED_OUTPUT FROM DUAL UNION ALL SELECT 'ABCD-012345-EFG-10zSe9K-' AS MAIN_STRING, (TRIM(REGEXP_REPLACE(SUBSTR('ABCD-012345-EFG-10zSe9K-',INSTR('ABCD-012345-EFG-10zSe9K-','-',1,3)+1),'[^0-9A-Za-z]',''))) AS FUNCTION_OUTPUT, '10zSe9K' AS EXPECTED_OUTPUT FROM DUAL UNION ALL SELECT 'ABCD-012345-EFG-10zSe9K-//1/23h' AS MAIN_STRING, (TRIM(REGEXP_REPLACE(SUBSTR('ABCD-012345-EFG-10zSe9K-//1/23h',INSTR('ABCD-012345-EFG-10zSe9K-//1/23h','-',1,3)+1),'[^0-9A-Za-z]',''))) AS FUNCTION_OUTPUT, '10zSe9K' AS EXPECTED_OUTPUT FROM DUAL UNION ALL SELECT 'ABCD-EFGH-HIJK-012345-10zSe9K' AS MAIN_STRING, (TRIM(REGEXP_REPLACE(SUBSTR('ABCD-EFGH-HIJK-012345-10zSe9K',INSTR('ABCD-EFGH-HIJK-012345-10zSe9K','-',1,3)+1),'[^0-9A-Za-z]',''))) AS FUNCTION_OUTPUT, '10zSe9K' AS EXPECTED_OUTPUT FROM DUAL
原执行结果
MAIN_STRING FUNCTION_OUTPUT EXPECTED_OUTPUT ABCD-012345-EFG-10vXRI47HU-1 10vXRI47HU1 10vXRI47HU ABCD-012345-EFG-10zSD0U/2 10zSD0U2 10zSD0U ABCD-012345-EFG-10ZsE8h -1 10ZsE8h1 10ZsE8h ABCD-012345-EFG- 10zSe9K 10zSe9K 10zSe9K ABCD-012345-EFG-.10zSe9K 10zSe9K 10zSe9K ABCD-012345-EFG-10zSe9K_2 10zSe9K2 10zSe9K ABCD-012345-EFG-10zSe9K. 10zSe9K 10zSe9K ABCD-012345--EFG-10zSe9K EFG10zSe9K 10zSe9K ABCD-012345-EFG-10zSe9K- 10zSe9K 10zSe9K ABCD-012345-EFG-10zSe9K-//1/23h 10zSe9K123h 10zSe9K ABCD-EFGH-HIJK-012345-10zSe9K 01234510zSe9K 10zSe9K
优化方案
直接使用REGEXP_SUBSTR匹配符合长度要求的字母数字子串,核心是精准定位7-12位连续字母数字组合,同时排除前后多余字符干扰。
优化后SQL
SELECT MAIN_STRING, REGEXP_SUBSTR(MAIN_STRING, '(^|\W)([A-Za-z0-9]{7,12})(\W|$)', 1, 1, 'i', 2) AS OPTIMIZED_OUTPUT, EXPECTED_OUTPUT FROM ( SELECT 'ABCD-012345-EFG-10vXRI47HU-1' AS MAIN_STRING, '10vXRI47HU' AS EXPECTED_OUTPUT FROM DUAL UNION ALL SELECT 'ABCD-012345-EFG-10zSD0U/2' AS MAIN_STRING, '10zSD0U' AS EXPECTED_OUTPUT FROM DUAL UNION ALL SELECT 'ABCD-012345-EFG-10ZsE8h -1' AS MAIN_STRING, '10ZsE8h' AS EXPECTED_OUTPUT FROM DUAL UNION ALL SELECT 'ABCD-012345-EFG- 10zSe9K ' AS MAIN_STRING, '10zSe9K' AS EXPECTED_OUTPUT FROM DUAL UNION ALL SELECT 'ABCD-012345-EFG-.10zSe9K' AS MAIN_STRING, '10zSe9K' AS EXPECTED_OUTPUT FROM DUAL UNION ALL SELECT 'ABCD-012345-EFG-10zSe9K_2' AS MAIN_STRING, '10zSe9K' AS EXPECTED_OUTPUT FROM DUAL UNION ALL SELECT 'ABCD-012345-EFG-10zSe9K.' AS MAIN_STRING, '10zSe9K' AS EXPECTED_OUTPUT FROM DUAL UNION ALL SELECT 'ABCD-012345--EFG-10zSe9K' AS MAIN_STRING, '10zSe9K' AS EXPECTED_OUTPUT FROM DUAL UNION ALL SELECT 'ABCD-012345-EFG-10zSe9K-' AS MAIN_STRING, '10zSe9K' AS EXPECTED_OUTPUT FROM DUAL UNION ALL SELECT 'ABCD-012345-EFG-10zSe9K-//1/23h' AS MAIN_STRING, '10zSe9K' AS EXPECTED_OUTPUT FROM DUAL UNION ALL SELECT 'ABCD-EFGH-HIJK-012345-10zSe9K' AS MAIN_STRING, '10zSe9K' AS EXPECTED_OUTPUT FROM DUAL ) t;
正则表达式说明
(^|\W):匹配字符串开头或非字母数字字符,确保目标子串前无多余字母数字([A-Za-z0-9]{7,12}):匹配7-12位连续字母数字,即目标子串(\W|$):匹配非字母数字字符或字符串结尾,确保目标子串后无多余字母数字'i':开启不区分大小写匹配(无需可省略)2:指定返回第2个捕获组内容,即我们需要的目标子串
执行该SQL后,所有案例的OPTIMIZED_OUTPUT将与EXPECTED_OUTPUT完全一致,解决原方案的所有适配问题。
内容的提问来源于stack exchange,提问作者venkatcg0
相关产品推荐
相关产品推荐

