如何在Oracle SQL中将字符串拆分为多段落并每行存一段落
SQL按空行拆分文本段落的正则问题解决
你的问题出在正则表达式的逻辑上:你用的[^'||CHR(10)||CHR(10)||']+是字符集取反,但字符集里的元素是单个字符,重复的字符会被忽略,所以这个表达式等价于[^'||CHR(10)||']+——也就是匹配所有不含单个换行的片段,自然会把每一行文本拆成单独的记录。
要实现按空行(两个连续换行)拆分段落,需要匹配两个换行之间的内容(包括单个换行),而非取反单个换行字符。以下是修正后的SQL代码:
SELECT msg.id, TRIM(REGEXP_SUBSTR(msg.text, '(.*?)(\n\n|$)', 1, LEVEL, 'n')) AS text_p FROM MSG CONNECT BY REGEXP_SUBSTR(msg.text, '(.*?)(\n\n|$)', 1, LEVEL, 'n') IS NOT NULL AND PRIOR msg.id = msg.id AND PRIOR SYS_GUID() IS NOT NULL;
关键说明:
(.*?)(\n\n|$):采用非贪婪模式匹配任意字符,直到遇到连续两个换行或文本结尾。'n'参数让.可以匹配换行符,这样就能捕获包含单个换行的整段内容。TRIM:可选,用于移除段落首尾的多余空白或换行,根据你的实际需求调整。PRIOR相关条件:避免当表中有多条数据时,CONNECT BY产生笛卡尔积,确保只拆分当前行的文本。
如果你的文本使用Windows风格的换行(CRLF,即CHR(13)||CHR(10)),只需把正则中的\n\n替换为\r\n\r\n即可:
SELECT msg.id, TRIM(REGEXP_SUBSTR(msg.text, '(.*?)(\r\n\r\n|$)', 1, LEVEL, 'n')) AS text_p FROM MSG CONNECT BY REGEXP_SUBSTR(msg.text, '(.*?)(\r\n\r\n|$)', 1, LEVEL, 'n') IS NOT NULL AND PRIOR msg.id = msg.id AND PRIOR SYS_GUID() IS NOT NULL;
运行修正后的代码,就能得到你期望的结果:将AAA\nBBB和CCC\nDDD分别作为两个段落拆分出来。
内容的提问来源于stack exchange,提问作者Filip
相关产品推荐
相关产品推荐

