【问题标题】:Extract data using REGEXP_SUBSTR使用 REGEXP_SUBSTR 提取数据
【发布时间】:2018-07-05 15:38:54
【问题描述】:

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

PSN932-52506252-BRS14774366CSN/SF-1/25JAN0524

以下是显示长度略有不同的进一步示例,我尝试提取的文本再次以粗体显示。如您所见,位置始终相同,但字母数字字符可以在“-”和“CSN”之间的任何位置,长度不同。

PSN932-49837056-DELAIR09364CSN/SF-66/25JAN0541

PSN932-51231434-H1001865CSN/SF-5/25JAN0546

PSN932-52648256-2EGA814CSN/SF-10/25JAN0549

获取第一个样本数据 (PSN932-52506252-BRS14774366CSN/SF-1/25JAN0524) 我创建了正确输出数据的以下查询,但是此查询不考虑文本可以由长度在 1-12 个字符之间变化的字母/数字字符组成

选择 REGEXP_SUBSTR('PSN932-52506252-BRS14774366CSN/SF-1/25JAN0524', '-(\D\D\D\d\d\d\d\d\d\d\d)',1 ,1, 'i',1) "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" 从双;

这个函数可以处理回车吗?

【问题讨论】:

  • 感谢这些工作人员,但当我嵌入到我的查询中时却没有。我注意到数据库中的数据似乎有回车并且存储如下所示,我们也可以处理回车吗? PSN(此处回车)932-52656855-4780080712(此处回车)CSN/SF-7/25JAN0604
  • 抱歉,我不确定如何将该替换函数嵌入到以下查询中 {SELECT REGEXP_SUBSTR(''MYColumn', '-(\w+)CSN', 1, 1, 'i', 1) 来自 MYTABLE 的“REGEXP_SUBSTR”;}
  • 如果您在必须获取的字符串部分中有 CR 怎么办?您要保留还是删除?
  • 永远不会有,但如果您需要考虑这一点,则可以将其删除。
  • 嘿别担心我已经想通了

标签: sql oracle regexp-substr


【解决方案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

【讨论】:

    【解决方案2】:

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

    Oracle docs

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

    所以模式应该改成-(\w+)CSN

    通过替换换行符/回车符可能最容易删除换行符。

    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;
    

    【讨论】:

      【解决方案3】:

      您可以通过组合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
      

      【讨论】:

        【解决方案4】:

        使用交替运算符来解释回车:

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

        【讨论】:

          【解决方案5】:

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

          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;
          

          【讨论】:

            猜你喜欢
            • 2020-10-10
            • 2019-12-13
            • 2012-06-26
            • 1970-01-01
            • 1970-01-01
            • 2021-04-23
            • 1970-01-01
            • 2016-06-17
            • 1970-01-01
            相关资源
            最近更新 更多