使用REGEXP_SUBSTR提取数据

时间:2018-01-26 09:50:46

标签: sql oracle regexp-substr

您好我在尝试使用REGEXP_SUBSTR函数从oracle数据库中提取单个字段中包含的文本的一部分。有问题的文字以粗体文字显示在下面" BRS14774366"。好消息是我试图提取的数据模式相当一致,因为它始终以" - "并且以" CSN"结尾,但是我尝试一致提取的文本并不总是相同,并且可以包含字母和数字字符,长度在1-12个字符之间。

PSN932-52506252-的 BRS14774366 CSN / SF-1 / 25JAN0524

以下是显示长度略有差异的其他示例,同样,我试图提取的文字以粗体显示。正如您所看到的,位置始终相同,但Alpha数字字符可以位于" - "之间。和" CSN"有不同的长度。

PSN932-49837056-的 DELAIR09364 CSN / SF-66 / 25JAN0541

PSN932-51231434-的 H1001865 CSN / SF-5 / 25JAN0546

PSN932-52648256-的 2EGA814 CSN / SF-10 / 25JAN0549

获取第一个样本数据(PSN932-52506252- BRS14774366 CSN / SF-1 / 25JAN0524)我创建了以下查询,正确输出数据,但此查询并未考虑文本可以包含长度在1-12个字符之间的字母/数字字符

选择   REGEXP_SUBSTR(' PSN932-52506252-BRS14774366CSN / SF-1 / 25JAN0524&#39 ;,                 ' - (\ D \ D \ D \ d \ d \ d \ d \ d \ d \ d \ d)',1,1,' i',1)& #34; REGEXP_SUBSTR"   来自双重;

以上查询的输出如下:

BRS14774366

任何人都可以告诉我如何在查询中格式化匹配模式,这样我就可以在" - "之间持续提取数据。和" CSN"?

一如既往地感谢人们可以提供的帮助吗?

更新 - 似乎存储的数据包含回车符,因此以下查询无效:

SELECT REGEXP_SUBSTR('PSN 932-52506252-BRS14774366 CSN/SF-1/25JAN0524', '-(\w+)CSN', 1, 1, 'i', 1) "REGEXP_SUBSTR" FROM DUAL;

如果数据是这样的话,

工作正常:

SELECT

REGEXP_SUBSTR(' PSN932-52506252-BRS14774366CSN / SF-1 / 25JAN0524',' - (\ w +)CSN',1,1,' i' ,1)" REGEXP_SUBSTR"   来自双重;

此功能可以处理回车吗?

5 个答案:

答案 0 :(得分:1)

这是你在找什么?

SQL> with
  2    s as (select 'SN932-52506252-BRS14774366CSN/SF-1/25JAN0524' n from dual union all
  3          select 'PSN932-49837056-DELAIR09364CSN/SF-66/25JAN0541' from dual union all
  4          select 'PSN932-51231434-H1001865CSN/SF-5/25JAN0546' from dual union all
  5          select 'PSN932-52648256-2EGA814CSN/SF-10/25JAN0549' from dual)
  6  select
  7    substr(replace(regexp_substr(s.n, '-([[:alpha:]]|[[:digit:]])+CSN'), 'CSN'), 2)
  8  from s;

SUBSTR(REPLACE(REGEXP_SUBSTR(S
--------------------------------------------------------------------------------
BRS14774366
DELAIR09364
H1001865
2EGA814

答案 1 :(得分:1)

您可以使用\ w匹配任何字母数字字符

Oracle docs

  

\瓦特   单词字符,定义为字母数字或下划线()字符。它相当于POSIX类[[:alnum:] ]。请注意,如果您不想包含下划线字符,则可以使用POSIX类[[:alnum:]]。

因此模式应更改为-(\w+)CSN

通过替换linefeed / carrige返回字符,可以最简单地删除换行符。

WITH s AS (select 'SN932-52506252-BRS14774366CSN/SF-1/25JAN0524' n from dual union all
       select 'PSN932-49837056-DELAIR09364' || chr(10) || 'CSN/SF-66/25JAN0541' from dual union all
       select 'PSN932-51231434-H1001865CSN/SF-5/25JAN0546' from dual union all
       select 'PSN932-52648256-2EGA814' || chr(13) || 'CSN/SF-10/25JAN0549' from dual),
remove_newlines as (select replace(replace(s.n, chr(10), ''), chr(13), '') n from s)

SELECT regexp_substr(s.n, '-(\w+)CSN', 1, 1, 'i', 1) "REGEXP_SUBSTR" FROM remove_newlines s;

答案 2 :(得分:0)

您可以通过合并instrsubstr来避免使用正则表达式。

这可能不那么容易阅读,但通常比正则表达式解决方案表现更好。

 with test(x) as (
        select 'PSN932-49837056-DELAIR09364CSN/SF-66/25JAN0541' from dual union all
        select 'PSN932-51231434-H1001865CSN/SF-5/25JAN0546' from dual union all
        select 'PSN932-52648256-2EGA814CSN/SF-10/25JAN0549' from dual
    )
    select substr(
                    substr(x, 1, instr(x, 'CSN') -1),
                    instr(
                            substr(x, 1, instr(x, 'CSN') -1),
                            '-',
                            -1
                         )+1
                 )
    from test

这使得部分达到了CSN:

substr(substr(x, 1, instr(x, 'CSN') -1)

然后从最后一个' - '开始获取此部分的子字符串。 :

instr(substr(x, 1, instr(x, 'CSN') -1), '-',-1)+1

答案 3 :(得分:0)

使用交替运算符来计算回车:

  SELECT
    regexp_substr('PSN932-52506252-BRS1477'
    || CHR(13)
    || '4366CSN/SF-1/25JAN0524','(([[:alnum:]]|['
    || CHR(13)
    || '])+)CSN') "REGEXP_SUBSTR"
FROM
    dual;

答案 4 :(得分:0)

即使查询看起来很丑,也只是发布了一个与正则表达式相关的替代方案。但是需要复制文本才能得到想要的结果。

SELECT
    substr('shusduhash-basb'
           || CHR(10)
           || 'daks-jsbabsCSN/', instr('shusduhash-basb'
                                       || CHR(10)
                                       || 'daks-jsbabsCSN/',
                                       '-',
                                       1,
                                       2) + 1,
           instr('shusduhash-basb'
                 || CHR(10)
                 || 'daks-jsbabsCSN/', 'CSN/', 1, 1) - instr('shusduhash-basb'
                                                             || CHR(10)
                                                             || 'daks-jsbabsCSN/', '-', 1, 2) - 1) x
FROM
    dual;