正则否定后缀负向环视不生效,如何将以NEW结尾的行输出置为NULL
原写法问题说明
你写的正则(?!NEW)$存在两个核心错误:
- 负向前瞻
(?!NEW)放在行尾锚点$前面,逻辑是断言行尾之后的内容不是NEW,而行尾之后不存在任何内容,这个断言永远为真,所以regexp_substr对所有行都会返回空字符串,而非NULL。 - decode逻辑也对应错误:你判断返回值为NULL时输出NULL,但实际返回的是空串,不会触发NULL判断,因此逻辑完全不生效。
修正方案
方案1:最简洁的实现(推荐)
直接用REGEXP_LIKE判断是否以NEW结尾,匹配则返回NULL,否则返回原值:
WITH aux ( dcalive ) AS ( SELECT 'DCA_LIVE_NEW' FROM dual UNION ALL SELECT 'DCA_LIVE_NEWS' FROM dual UNION ALL SELECT 'DCA_LIVE_NO_RECALL' FROM dual UNION ALL SELECT 'DCA_LIVE' FROM dual ) SELECT a.*, CASE WHEN REGEXP_LIKE(dcalive, 'NEW$') THEN NULL ELSE dcalive END desired_output FROM aux a;
方案2:用负向环视实现(符合你最初的实现思路)
如果要坚持用环视逻辑,需要改用负向后发环视,判断字符串末尾3个字符不是NEW,匹配到就返回原值,没匹配到返回NULL:
WITH aux ( dcalive ) AS ( SELECT 'DCA_LIVE_NEW' FROM dual UNION ALL SELECT 'DCA_LIVE_NEWS' FROM dual UNION ALL SELECT 'DCA_LIVE_NO_RECALL' FROM dual UNION ALL SELECT 'DCA_LIVE' FROM dual ) SELECT a.*, regexp_substr(dcalive, '^.*(?<!NEW)$') desired_output FROM aux a;
两种方案运行后都能得到你预期的输出:
DCALIVE DESIRED_OUTPUT -------------------------------------- DCA_LIVE_NEW NULL DCA_LIVE_NEWS DCA_LIVE_NEWS DCA_LIVE_NO_RECALL DCA_LIVE_NO_RECALL DCA_LIVE DCA_LIVE
内容的提问来源于stack exchange,提问作者banana_99
相关产品推荐
相关产品推荐

