首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何根据Oracle SQL中的模式提取两个字符串之间的数据

如何根据Oracle SQL中的模式提取两个字符串之间的数据
EN

Stack Overflow用户
提问于 2021-02-14 14:30:01
回答 2查看 426关注 0票数 0

我希望根据特定的模式从oracle SQL中类型为CLOB的列中提取数据。我用regex尝试了不同的东西,到目前为止都没有用。

PFB关于数据的外观和预期输出的示例。样本数据:

我应该在单词列表之前提取CLOB列,直到.(点) PS: CLOB可以在模式中有CR、LF / Carriage返回。预期产出:

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-02-14 20:39:07

我就是这样做的。请注意以下几点:

  1. 输出保留输入中存在的换行符。您没有提到删除它们的任何内容;但是,您的输出没有显示它们。在任何情况下--如果需要的话,它们可以被移除,但这是一个不相关的过程。
  2. 您说的是"word“,但很明显,您使用它的意义与正则表达式中的常用用法不同。在regexp中,“单词字符”只是字母、数字和下划线;然而,您的“单词”包括括号、等号,还有谁知道还有什么。我把“单词”解释为任何连续的非空格字符序列。

以下是我们如何重新创建您的数据。当您在这里问一个问题时,您应该如何提供示例数据--而不是我们无法在SQL编辑器中复制和粘贴的图像。

代码语言:javascript
运行
复制
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 *Plus的接口),您可能需要更改一些设置,这样输出就不会被截断。特别是在SQL*Plus中,默认情况下CLOB列被截断为80个字符;我必须

代码语言:javascript
运行
复制
set long 100

查询和输出:

代码语言:javascript
运行
复制
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:后面的字符作为--少数为连续的字符,非句号字符(这将匹配空格和换行符,特别是换行符)--允许匹配--该匹配以一个或多个空白字符继续,后面跟着一个单词(字符串为1个或多个非空白字符)和一个文字句点(\.)。

我们必须返回的表达式被括在括号中,这样我们就可以从regexp_substr返回它。这样的表达式被称为“捕获组”。出于必要,regexp包括另一个捕获组(\s|^),因此我们必须返回的捕获组是regexp中的第二个。这就是regexp_substr的最后一个参数:它指示函数返回第二个捕获组。

注意,句点(与括号表达式中转义这一更为普遍的概念有关):在正则表达式的末尾,句点必须转义以表示文字句点,而不是“任何字符”;然而,在(被否定的)括号表达式[^.]*?中,句点--代表文字句点,而不是“任何字符”--是而不是转义。Oracle遵循POSIX标准的ERE (Extended正则表达式)方言,该标准指出转义序列在括号表达式中无效。这与其他正则表达式方言不同,并使许多用户感到困惑。

票数 1
EN

Stack Overflow用户

发布于 2021-02-14 15:07:16

也许有更有效的方法来做到这一点,但以下几点似乎是可行的:

首先,我使用TRANSLATE用空格替换换行符,然后使用regex查找LIST:.之间的任何内容。然后使用SUBSTRINSTR删除最后的"word“。我使用了一个子查询来避免重复第一步。

代码语言:javascript
运行
复制
SELECT
  SubQuery.COL_A,
  SUBSTR(SubQuery.WithWordAndDot, 1, INSTR(SubQuery.WithWordAndDot,' ',-1)-1) AS Result
FROM 
(
SELECT
  COL_A,
  REGEXP_SUBSTR(TRANSLATE(COL_B, CHR(10)||CHR(13), ' '),'LIST:[^\.]+\.') as WithWordAndDot
FROM MyTable
 ) SubQuery
 ;
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66196404

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档