首页 > 解决方案 > 如何缩短正则表达式

问题描述

我有一个如下的 RegExp,当我在 Oracle SQL 中使用它时,出现 ORA-12723 错误,我怎样才能让它以最短的格式出现?

WITH test_data ( str ) AS (
    SELECT 'This is extension 1234, here is mobile phone: 090-1234-5678 maybe 8+24-98765432. Then +1-(234)-090-345 also 86 21-4566-4556' AS str FROM DUAL
)
SELECT TRIM(
    TRAILING ',' FROM
    REGEXP_REPLACE(
       str,
       '.*?(\+?\d{1,11}[-,\+]\d{1,11}[-,\+]\d{1,11}[-,\+]\d{1,11}[-,\+]\d{1,11}[-,\+]\d{3,11}|\+?\d{1,11}[-,\+]\d{1,11}[-,\+]\d{1,11}[-,\+]\d{1,11}[-,\+]\d{3,11}|\+?\d{1,11}[-,\+]\d{1,11}[-,\+]\d{1,11}[-,\+]\d{3,11}|\+?\d{1,11}[-,\+]\d{1,11}[-,\+]\d{3,11}|\+?\d{1,11}[-,\+]\d{3,11}|\d{3,11}|$)',
       '\1,'
    )
) AS replaced_str
FROM test_data

结果我想知道如下:

1234,090-1234-5678,8+24-98765432,+1-(234)-090-345,86 21-4566-4556

标签: oracleregexp-replaceregexp-substr

解决方案


考虑这种方法。这用于CONNECT BY遍历字符串并将其解析为由空格或行尾分隔的元素。然后对于每个元素,删除非数字字符('\D')。最后用于LISTAGG()将元素放回一个逗号分隔的字符串中。

WITH test_data(str) AS (
    SELECT 'Txa233g141b Ta233141 Ta233142 Ta233147zz Ta233xx148zz' AS str FROM DUAL
)
SELECT listagg(regexp_replace(regexp_substr(str, '(.*?)( |$)', 1, level, null, 1), '\D'), ',') 
         within group (order by str) replaced_str
FROM test_data
connect by level <= regexp_count(str, ' ') + 1;


REPLACED_STR                                                                    
--------------------------------------------------------------------------------
233141,233141,233142,233147,233148    

1 row selected.

推荐阅读