SQL正则表达式,用于根据分隔符' / n'将列(字符串)拆分为多行

时间:2016-04-22 04:34:23

标签: sql regex oracle

我必须将列拆分为多行。该列存储字符串,我们必须根据'/n'

拆分分隔符

编写了以下查询。但无法指定^[/n]。字符串中的其他'n'也将被删除。请帮助解析字符串

WITH sample AS 
( SELECT 101 AS id, 
        'Name' test, 
        '3243243242342342/n12131212312/n123131232/n' as attribute_1, 
        'test value/nneenu not/nhoney' as attribute_2
   FROM DUAL 
) 
-- end of sample data
SELECT id,
       test,
       regexp_substr(attribute_1,'[^/n]+', 1, column_value),
       regexp_substr(attribute_2,'[^/]+', 1, column_value)
  FROM sample,
       TABLE(
         CAST(
           MULTISET(SELECT LEVEL 
                       FROM dual  
                    CONNECT BY LEVEL <= LENGTH(attribute_1) - LENGTH(replace(attribute_1, '/n')) + 1
                   ) AS sys.OdciNumberList
         )
       )
 WHERE regexp_substr(attribute_1,'[^/n]+', 1, column_value) IS NOT NULL
/

4 个答案:

答案 0 :(得分:0)

你需要使用类[[:cntrl:]] 和&#39; [^ / n] +&#39;也不是语法上的好。

逃脱字符是&#39; \&#39;并且你不能使用[]来&#34;包装&#34;特殊字符,你需要使用()代替。(即分组)

如果你想忽略CR(例如&#39; \ n&#39;),请在regexp_substr中的sec param中使用[^ [:cntrl:]]

更多帮助:http://psoug.org/snippet/Regular-Expressions--Regexp-Cheat-Sheet_856.htm

答案 1 :(得分:0)

<强> 假设

/n应该表示\n匹配换行符(严格来说[Posix]说一个LF字符(十六进制x0a))。

如果此假设出错,请使用(^|/n)(([^/]|/+[^n])+)作为正则表达式,并使用regexp_substr(attribute_1,'(^|/n)(([^/]|/+[^n])+)', 1, column_value, '', 2)提取感兴趣的部分。

<强> 解决方案

您无法在字符类中的转义语法中指定控制字符。使用posix字符类[:cntrl:]可以工作,但是会受到其他字符的影响;出于实际目的,TAB(#x09)可能会令人讨厌。

但是,您可以指定正则表达式字符类中的所有字符,这些字符组成文字中的模式字符串并调用chr函数:

   -- ...
    '3243243242342342'||chr(13)||chr(10)||'12131212312'||chr(13)||chr(10)||'123131232'||chr(13)||chr(10) as attribute_1, 
    'test value'||chr(13)||chr(10)||'neenu not'||chr(13)||chr(10)||'honey' as attribute_2
   -- ...
   regexp_substr(attribute_1,'[^'||chr(13)||chr(10)||']+', 1, column_value),
   regexp_substr(attribute_2,'[^'||chr(13)||chr(10)||']+', 1, column_value)
   -- ...

您可能想在sqlplus中查看以下测试查询(cr / lfs是文字的一部分;复制到文本编辑器中,检查是否保留了cr / lfs,如果没有则重新插入,删除结果在sqlplus):

select regexp_substr('adda
yxcv','[^'||CHR(10)||CHR(13)||']+', 1, 2) from dual;
select regexp_substr('ad'||CHR(9)||'da
yxcv','[^[:cntrl:]]+', 1, 2) from dual;

答案 2 :(得分:0)

webview

答案 3 :(得分:0)

第一种选择是修复数据模型,因为以这种方式存储的数据不是最佳的。无论如何,请尝试此版本以及更多测试数据。我调整了正则表达式:

WITH sample AS 
( SELECT 101 AS id, 
        'Name' test, 
        '3243243242342342/n12131212312/n123131232/n' as attribute_1, 
        'test value/nneenu not/nhoney' as attribute_2
   FROM DUAL 
) 
-- end of sample data
SELECT id,
       test,
       regexp_substr(attribute_1,'(.*?)(/n|$)', 1, column_value, NULL, 1),
       regexp_substr(attribute_2,'(.*?)(/n|$)', 1, column_value, NULL, 1)
  FROM sample,
       TABLE(
         CAST(
           MULTISET(SELECT LEVEL 
                       FROM dual  
                    --CONNECT BY LEVEL <= LENGTH(attribute_1) - LENGTH(replace(attribute_1, '/n')) + 1
                      -- Counts substrings ending with the delimiter.
                      CONNECT BY LEVEL <= REGEXP_COUNT(attribute_1, '.*?/n')                    
                   ) AS sys.OdciNumberList
         )
       )
 WHERE regexp_substr(attribute_1,'(.*?)(/n|$)', 1, column_value, NULL, 1) IS NOT NULL
/