REGEXP_SUBSTR未处理chr(10)字符:含换行符字符串切割异常问询
问题原因与解决方案
这个问题的核心在于Oracle正则表达式的默认匹配行为:默认情况下,.元字符只能匹配除换行符(包括chr(10)换行、chr(13)回车等)之外的任意字符。
具体分析
你的第一个SQL中,字符串是Line1~-delim~-Line2,(.*?)可以正常匹配到Line1——因为从起始位置到~-delim~-之间没有换行符,.能覆盖所有字符。
但第二个SQL里,Line1后面多了chr(10)换行符,此时.*?遇到换行符就会停止匹配,无法跨过换行符找到后面的~-delim~-分隔符。这就导致当LEVEL=1时,REGEXP_SUBSTR找不到符合(.*?)(~-delim~-|$)规则的有效匹配;只有当LEVEL=2时,才能匹配到分隔符之后的Line2,最终只输出这一个结果。
两种解决方法
方法1:启用换行匹配模式(n参数)
在REGEXP_SUBSTR的match_param参数位置传入'n',让.元字符匹配包括换行符在内的所有字符:
SELECT REGEXP_SUBSTR ( str, '(.*?)(~-delim~-|$)', 1, LEVEL, 'n', 1 ) output FROM ( SELECT 'Line1'||chr(10)||'~-delim~-Line2' AS str FROM DUAL ) CONNECT BY LEVEL <= REGEXP_COUNT (str, '~-delim~-') + 1
方法2:修改正则表达式匹配所有字符
用[\s\S]替代.——\s匹配所有空白字符(含换行),\S匹配所有非空白字符,两者结合就能覆盖任意字符,无需依赖匹配模式参数:
SELECT REGEXP_SUBSTR ( str, '([\s\S]*?)(~-delim~-|$)', 1, LEVEL, NULL, 1 ) output FROM ( SELECT 'Line1'||chr(10)||'~-delim~-Line2' AS str FROM DUAL ) CONNECT BY LEVEL <= REGEXP_COUNT (str, '~-delim~-') + 1
执行任意一种修改后的SQL,都能得到你预期的Line1(包含后面的换行符)和Line2两个结果。
内容的提问来源于stack exchange,提问作者Deepak Senthilkumar
相关产品推荐
相关产品推荐

