regexp_substr跳过空位

时间:2013-09-20 14:32:47

标签: regex oracle plsql

使用此代码返回管道分隔字符串中的第n个值...

regexp_substr(int_record.interfaceline, '[^|]+', 1, i)

当所有值都存在时,它可以正常工作

Mike|Male|Yes|20000|Yes因此3rd值为Yes(正确)

但如果字符串是

Mike|Male||20000|Yes,第三个值是20000(不是我想要的)

如何判断表达式不跳过空值?

TIA

麦克

5 个答案:

答案 0 :(得分:6)

regexp_substr以这种方式工作:

  

如果出现次数大于1,则数据库搜索   第二次出现以第一个字符开头   第一次出现模式,依此类推。这种行为是不同的   从SUBSTR函数开始搜索第二个函数   在第一次出现的第二个字符处出现。

因此模式[^ |]将查找非管道,这意味着它将跳过连续管道(“||”)寻找非管道字符。

您可以尝试:

select trim(regexp_substr(replace('A|test||string', '|', '| '), '[^|]+', 1, 4)) from dual;

这将取代“|”使用“|”并允许您根据模式匹配[^ |]

答案 1 :(得分:1)

我对CSV文件有类似的问题,因此我的分隔符是分号( select regexp_substr(';2;;4;', '[^;]+', 1, i) from dual
因此,我从以下表达式开始:

i

^;从1迭代到5。

当然也没有用。

要获取空白部分,我只是说它们可以在开头(;;)或在中间(;$)或结尾(select regexp_substr(';2;;4;', '[^;]+|^;|;;|;$', 1, i) from dual )。或所有这些加在一起给出:

i

信不信由你:从1到5测试key有用!

但我们不要忘记最后的细节:通过这种方法,您可以得到;对于最初为空的字段。 接下来的几行显示了如何摆脱它们,轻松地将它们替换为空字符串(null):

stage1为(

从对偶中选择regexp_substr('; 2 ;; 4;','[^;] + | ^; | ;; | $$,1,2)作为F

选择当F喜欢'%;'的情况;然后“否则F从stage1结束

答案 2 :(得分:0)

行。这应该是最适合您的解决方案。

SELECT
      REGEXP_REPLACE ( 'Mike|Male||20000|Yes',
                    '^([^|]*\|){2}([^|]*).*$',
                    '\2' )
          TEXT
FROM
      DUAL;

所以对你的问题

SELECT
      REGEXP_REPLACE ( INCOMINGSTREAMOFSTRINGS,
                    '^([^|]*\|){N-1}([^|]*).*$',
                    '\2' )
          TEXT
FROM
      DUAL;

- INCOMINGSTREAMOFSTRINGS是带分隔符的完整字符串

- 你应该传递n-1来获得第n个位置

替代2:

WITH T AS (SELECT 'Mike|Male||20000|Yes' X FROM DUAL)
SELECT
      X,
      REGEXP_REPLACE ( X,
                    '^([^|]*).*$',
                    '\1' )
          Y1,
      REGEXP_REPLACE ( X,
                    '^[^|]*\|([^|]*).*$',
                    '\1' )
          Y2,
      REGEXP_REPLACE ( X,
                    '^([^|]*\|){2}([^|]*).*$',
                    '\2' )
          Y3,
      REGEXP_REPLACE ( X,
                    '^([^|]*\|){3}([^|]*).*$',
                    '\2' )
          Y4,
      REGEXP_REPLACE ( X,
                    '^([^|]*\|){4}([^|]*).*$',
                    '\2' )
          Y5
FROM
      T;

替代3:

SELECT
      REGEXP_SUBSTR ( REGEXP_REPLACE ( 'Mike|Male||20000|Yes',
                                '\|',
                                ';' ),
                   '(^|;)([^;]*)',
                   1,
                   1,
                   NULL,
                   2 )
          AS FIRST,
      REGEXP_SUBSTR ( REGEXP_REPLACE ( 'Mike|Male||20000|Yes',
                                '\|',
                                ';' ),
                   '(^|;)([^;]*)',
                   1,
                   2,
                   NULL,
                   2 )
          AS SECOND,
      REGEXP_SUBSTR ( REGEXP_REPLACE ( 'Mike|Male||20000|Yes',
                                '\|',
                                ';' ),
                   '(^|;)([^;]*)',
                   1,
                   3,
                   NULL,
                   2 )
          AS THIRD,
      REGEXP_SUBSTR ( REGEXP_REPLACE ( 'Mike|Male||20000|Yes',
                                '\|',
                                ';' ),
                   '(^|;)([^;]*)',
                   1,
                   4,
                   NULL,
                   2 )
          AS FOURTH,
      REGEXP_SUBSTR ( REGEXP_REPLACE ( 'Mike|Male||20000|Yes',
                                '\|',
                                ';' ),
                   '(^|;)([^;]*)',
                   1,
                   5,
                   NULL,
                   2 )
          AS FIFTH
FROM
      DUAL;

答案 3 :(得分:0)

您可以使用以下内容:

with l as (select 'Mike|Male||20000|Yes' str from dual)
select regexp_substr(str,'(".*"|[^|]*)(\||$)',1,level,null,1) 
from dual,l 
where level=3/*use any position*/ connect by level <= regexp_count(str,'([^|]*)(\||$)')

答案 4 :(得分:0)

作为@tbone响应的补充...

奇怪的是,我的Oracle无法识别此列表中的空格字符:[^|] 在这种情况下,可能会造成混淆,并且很难意识到出了什么问题。 尝试使用此正则表达式([^|]| )+。另外,要检测可能的第一个空白项目,最好将分隔符替换为空格之前的空格,而不是之后的空格: ' |'

trim(regexp_substr(replace('A|test||string', '|', ' |'), '([^|]| )+', 1, 4))