regex 如何在Oracle SQL中将字符串拆分为多个段落并将段落存储在新行中?

qxsslcnc  于 2023-04-22  发布在  Oracle
关注(0)|答案(1)|浏览(118)

我一直在努力在SQL中使用正则表达式。
基本上,我有一个包含文本的列,但每个段落都应该在新的一行中。
表消息中的行示例:

|  |AAA
|  |BBB
|1 |
|  |CCC
|  |DDD

我使用以下SQL代码:

SELECT msg.id, regexp_substr(msg.text, '[^'||CHR(10)||CHR(10)||']+', 1, LEVEL) as text_p
FROM MSG
CONNECT BY regexp_substr(msg.text, '[^'||CHR(10)||CHR(10)||']+', 1, LEVEL) IS NOT NULL;

在哪里我想得到以下内容:

|1 |AAA
|  |BBB
|--|
|2 |CCC
|  |DDD

但我得到以下结果:

|1 |AAA
|2 |BBB
|3 |CCC
|4 |DDD

我不知道为什么会出现这种情况,因为当我在www.example.com上尝试正则表达式时regexr.com,选择\n\n会选择我想要拆分的段落空间,但否定不会选择整个段落作为一个组(即A和B作为一个,C和D作为另一个)。
我试过使用CHR(13)CHR(10),但它仍然不起作用。

cngwdvgl

cngwdvgl1#

正则表达式'[^'||CHR(10)||CHR(10)||']+'的含义是任何不是CHR(10)CHR(10)的字符重复一次或多次。它与表达式'[^'||CHR(10)||']+'相同
你想要的是匹配零个或多个字符,但尽可能少,'(.*?)',直到你找到两个新行字符或字符串'(' || CHR(10)||CHR(10)||'|$)'的结尾,并只输出第一个捕获组:

SELECT msg.id,
       regexp_substr(
         msg.text,
         '(.*?)(' || CHR(10)||CHR(10)||'|$)',
         1,
         LEVEL,
         'n',    -- Allow . to match newlines
         1       -- Return the first capturing group
       ) as text_p
FROM   MSG
CONNECT BY
       LEVEL < REGEXP_COUNT(msg.text, '(.*?)(' || CHR(10)||CHR(10)||'|$)');
  • 注意:在CONNECT BY子句中使用<而不是<=,因为正则表达式将匹配零宽度的最终项。*

其中,对于样本数据:

CREATE TABLE msg (id, text) AS
SELECT 1, 'AAA
BBB

CCC
DDD' FROM DUAL;

输出:
| ID|正文_P|
| --------------|--------------|
| 1|AAA血脑屏障|
| 1|CCCDDD|
fiddle

相关问题