regexp_substr 用于换行的模式,其中分隔符是换行符。甲骨文 19c

Posted

技术标签:

【中文标题】regexp_substr 用于换行的模式,其中分隔符是换行符。甲骨文 19c【英文标题】:regexp_substr Pattern for line splitting where separator is line break. Oracle 19c 【发布时间】:2021-09-24 07:20:43 【问题描述】:

如何正确组合 regexp_substr 的掩码,以便获取每个值在输出的新行中的形式的数据?以及如何从结果中删除空值,str 字段?当最后一个值是行首时就是这种情况。 我这样做了,但是这个查询不返回结果,在regexp_substr 我使用掩码 '[' || chr (10) || ']'。

select ft.field_id , regexp_substr(ft.validation_data,'['||chr(10)||']', 1, rownum) str 
            from mytable ft
            where ft.validation_data is not null
connect by rownum <= regexp_count(ft.validation_data,'['||chr(10)||']');

mytablevalidation_data字段中,每行数据如下所示:

-
ПДКП КА
ДКП
ДКП(Знач1/Знач2)
ПДУПА
ДУПА
<-There is a space here

或者

Знач1/Знач2
Знач3/Знач4
Знач5/Знач6

每个值都由换行符分隔。在每一行的开头可以有一个字符 - 或者一个或多个空格。 我需要得到这个视图:

field_id str
1 -
2 ПДКП
3 ДКП
4 ДКП(Знач1/Знач2)
5 ДУПА
6 ДКП(Знач1/Знач2)
7 Знач1/Знач2

【问题讨论】:

还能添加原始表格内容吗? 你确定返回结果吗?例如。 ПДУПА不见了,ДКП(Знач1/Знач2)返回两次,你真的需要单独返回ДКП(Знач1/Знач2)Знач1/Знач2吗? 最简单的方法就是复制两行之间的内容并将其粘贴到正则表达式中。或者用dump(&lt;your newline&gt;, 16)检查它的内部表示(看看它是cr还是lf或者两者兼有) 【参考方案1】:

根据标题和使用的CHR(10) 字符,预期的结果集似乎是错误的。由于您只想按换行符拆分字符串,因此无需重复,无需提取括号内的子字符串...

我假设有一个来自表的id 列,以及打算通过使用rownum 顺序生成的field_id 列。但是,如果在表中包含多于一行时使用rownum 伪列替换field_id 的值,则查询将无法产生良好的结果。然后将其替换为level 关键字。

考虑到所有这些事实,您可以将查询转换为以下查询

 SELECT id, level AS field_id,
        REGEXP_SUBSTR(validation_data, '[^'||CHR(10)||']+', 1, level) AS str
   FROM mytable 
CONNECT BY level <= REGEXP_COUNT(validation_data, CHR(10))+1
    AND PRIOR SYS_GUID() IS NOT NULL
    AND PRIOR id = id        

或者

 SELECT id, column_value AS field_id,
        REGEXP_SUBSTR(validation_data, '[^'||CHR(10)||']+', 1, column_value) AS str
   FROM mytable,
        TABLE(CAST(MULTISET(SELECT level
                              FROM dual 
                           CONNECT BY level <= 
                     REGEXP_COUNT(validation_data,CHR(10))+1) AS sys.odcivarchar2list ))

Demo

Edit :如果你想用空格去掉生成的行,那么 添加

AND REGEXP_SUBSTR(RTRIM(validation_data), '[^'||CHR(10)||']+', 1,level) IS NOT NULL
首先,

WHERE REGEXP_SUBSTR(RTRIM(validation_data), '[^'||CHR(10)||']+', 1,column_value) IS NOT NULL

到第二个查询。

【讨论】:

谢谢。你的回答对我来说是最合适最完整的。 我编辑了这个问题。在带有数据的示例中,我指出了我有空格的位置 @Ambasador PRIOR 用于在分层查询中引用父行,SYS_GUID() 用于生成全局唯一标识符(由 16 个字节组成)。例如,两者都用于通过为每个记录生成单独的标识来区分记录。 嗨@Ambasador,您可以查看link1、link2 和link3 非常感谢【参考方案2】:

如果你的值里面不包含空格,你可以简单地使用否定的空格类

select rownum, regexp_substr(tt, '\S+', 1, rownum)
from (
select '-
ПДКП
ДКП
ДКП(Знач1/Знач2)
ПДУПА
ДУПА' tt from dual
)
connect by level <= regexp_count(tt, '\S+');

https://dbfiddle.uk/?rdbms=oracle_11.2&fiddle=bd6c0270ce753da4033e79d4bd5b18c3

如果可以 - 使用'[^'||chr(13)||chr(10)||']+'

【讨论】:

如果值中包含空格,例如ПДКП КА,那么КА会换行,但必须在一行ПДКП КА【参考方案3】:

或者这个:

with mytable as (
select 1 field_id,
'1asdasdad5
 2asdasd
3ФЫВФЫВ' validation_data
from dual
)
select ft.field_id, regexp_substr(ft.validation_data, '[^'||chr(10)||']+',1,level) str
from mytable ft
where ft.validation_data is not null
connect by rownum <= regexp_count(ft.validation_data, chr(10))+1 

【讨论】:

您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center。

以上是关于regexp_substr 用于换行的模式,其中分隔符是换行符。甲骨文 19c的主要内容,如果未能解决你的问题,请参考以下文章

PHP:用于换行的测试行长度

js计算li不换行的情况下,ul的宽度--用于做有滚动的导航条

如何将模式匹配用于针对 JSON 或 JSON 行的 SQL 样式查询

CFile CStdioFile CArchive 文件操作之异同(详细)

JScrollBar 内自动换行的布局

如何在jsp页面上规定每行显示的字数,然后自动换行