我会这样做。注意几点:
- 输出保留输入中存在的换行符。你没有
说出关于删除它们的任何信息;但是,您的输出未显示
他们。无论如何 - 如果需要,它们可以被移除,但这是一个
不相关的过程。
- 您说的是“单词”,但显然您使用的是不同的意思
来自正则表达式中的常见用法。在正则表达式中,“字
characters" 只是字母、数字和下划线;但您的
“单词”包括括号、等号,还有谁知道呢。我将“单词”解释为任何
连续的非空白字符序列。
我们可以通过以下方式重新创建您的数据。当您在这里提出问题时,您应该以这种方式提供示例数据 - 而不是我们无法在 SQL 编辑器中复制和粘贴的图像。
CREATE TABLE sample_data( col_a varchar2(20), col_b CLOB );
INSERT INTO sample_data VALUES
('12345', to_clob(
'Created:2/28/2019
Updated:1/19/2021
LIST:[ABC][DEF][GHI]
[LMNO][PQRST]
[Location=BLAH].[City=BLAH]'));
INSERT INTO sample_data VALUES
('12346', to_clob(
'Created:2/28/2019
Updated:1/19/2021
LIST:[ABC][DEF][GHI]
[LMNO][PQRST]
[SOC].[RAW]'));
commit;
然后这里是查询和输出。请注意,根据您的界面(在我的例子中:SQL Developer,它使用类似 SQL*Plus 的界面),您可能需要更改一些设置以使输出不会被截断。特别是在 SQL*Plus 中,CLOB 列默认被截断为 80 个字符;我不得不
set long 100
所以 - 查询和输出:
select col_a, col_b,
regexp_substr(col_b, '(\s|^)(LIST:[^.]*?)\s+\S+\.', 1, 1, null, 2)
as result
from sample_data
;
COL_A COL_B RESULT
----- ------------------------------ ------------------------------
12345 Created:2/28/2019 LIST:[ABC][DEF][GHI]
Updated:1/19/2021 [LMNO][PQRST]
LIST:[ABC][DEF][GHI]
[LMNO][PQRST]
[Location=BLAH].[City=BLAH]
12346 Created:2/28/2019 LIST:[ABC][DEF][GHI]
Updated:1/19/2021 [LMNO][PQRST]
LIST:[ABC][DEF][GHI]
[LMNO][PQRST]
[SOC].[RAW]
正则表达式匹配单个空格字符或字符串的开头((\s|^)),然后是字符LIST:,后跟few连续,非- 句点字符(这将匹配空格和换行符,特别是)以允许匹配 - 以一个或多个空白字符继续,后跟一个单词(1个或多个非空白字符的字符串)和文字期间 (\.)。
我们必须返回的表达式用括号括起来,以便我们可以从regexp_substr 返回它。这种表达方式称为“捕获组”。正则表达式包含另一个捕获组(\s|^),出于必要(交替),因此我们必须返回的捕获组是正则表达式中的第二个。这就是 regexp_substr 的最后一个参数所做的:它指示函数返回第二个捕获组。
请注意句点的一个特殊之处(与括号表达式中转义的更一般概念有关):句点必须转义以表示正则表达式末尾的文字句点,而不是“任何字符” ;但是,在(否定的)括号表达式 [^.]*? 中,句点 - 表示文字句点,而不是“任何字符” - 被 not 转义。 Oracle 遵循 POSIX 标准的 ERE(扩展正则表达式)方言,该标准规定转义序列在括号表达式中无效。这与其他正则表达式方言不同,让很多用户感到困惑。