使用此代码返回管道分隔字符串中的第 n 个值...
regexp_substr(int_record.interfaceline, '[^|]+', 1, i)
当所有值都存在时它工作正常
Mike|Male|Yes|20000|Yes
所以3rd
值是Yes
(正确的)
但如果字符串是
Mike|Male||20000|Yes
,第三个值是20000
(不是我想要的)
如何告诉表达式不要跳过空值?
TIA
麦克风
regexp_substr 以这种方式工作:
如果occurrence 大于1,则数据库从第一次出现pattern 之后的第一个字符开始搜索第二次出现,依此类推。此行为不同于 SUBSTR 函数,后者在第一次出现的第二个字符处开始搜索第二次出现。
所以模式 [^|] 将寻找非管道,这意味着它将跳过连续管道(“||”)寻找非管道字符。
你可以试试:
select trim(regexp_substr(replace('A|test||string', '|', '| '), '[^|]+', 1, 4)) from dual;
这将替换“|” 带有“|”并允许您根据模式 [^|] 进行匹配
我在 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 测试它有效!
但我们不要忘记最后的细节:通过这种方法,你会得到 ; 对于最初为空的字段。接下来的几行展示了如何摆脱它们,用空字符串(nulls)轻松替换它们:
与阶段1为(
从对偶中选择 regexp_substr(';2;;4;', '[^;]+|^;|;;|;$', 1, 2) 作为 F
)
当 F like '%;' 时选择 case then '' else F 从 stage1 结束
您可以使用以下内容:
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,'([^|]*)(\||$)')
好的。这应该是您的最佳解决方案。
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;
作为@tbone 响应的补充......
奇怪的是,我的 oracle 无法识别此列表中的空格字符:[^|]
在这种情况下,您可能会感到困惑并且很难意识到出了什么问题。试试这个正则表达式([^|]| )+
。此外,要检测可能的第一个空白项,最好将分隔符替换为之前的空格,而不是之后:
' |'
trim(regexp_substr(replace('A|test||string', '|', ' |'), '([^|]| )+', 1, 4))