Sql 使用REGEXP\u SUBSTR提取数据

Sql 使用REGEXP\u SUBSTR提取数据,sql,oracle,regexp-substr,Sql,Oracle,Regexp Substr,大家好,我正在尝试使用REGEXP_SUBSTR函数从oracle数据库中提取单个字段中包含的部分文本。“BRS14774366”下方的黑体文本显示了相关文本。好消息是,我试图提取的数据模式是相当一致的,因为它总是以“-”开头,以“CSN”结尾,但是我试图一致提取的文本并不总是相同的,可以由字母和数字字符组成,长度在1-12个字符之间 PSN932-52506252-BRS14774366CSN/SF-1/25JAN0524 下面是进一步的例子,显示了长度上的细微差异,同样,我试图提取的文本以粗

大家好,我正在尝试使用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--<强> BRS1477366<强> CSN/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\u SUBSTR” 来自双重

以上查询的输出如下:

BRS14774366

有人能告诉我如何格式化查询中的匹配模式,以便我能够一致地提取“-”和“CSN”之间的数据吗

一如既往地感谢人们能提供的任何帮助

更新-似乎存储的数据包含回车符,因此以下查询不起作用:

选择
REGEXP_SUBSTR('PSN
932-52506252-BRS14774366
CSN/SF-1/25JAN0524','-(\w+)CSN',1,1,'i',1)“REGEXP_SUBSTR”
来自双重

如果数据如下所示,则工作正常:

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


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

这是您要找的吗

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

这就是你要找的吗

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

通过组合
instr
substr
,可以避免使用正则表达式

这可能不太容易阅读,但通常比regexp解决方案性能更好

 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

通过组合
instr
substr
,可以避免使用正则表达式

这可能不太容易阅读,但通常比regexp解决方案性能更好

 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

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

\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;

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

\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;

使用替换运算符对回车进行说明:

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

使用替换运算符对回车进行说明:

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

尽管查询看起来很难看,但只是发布了一个与regexp相关的替代项。但是需要复制文本才能获得所需的结果

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;

尽管查询看起来很难看,但只是发布了一个与regexp相关的替代项。但是需要复制文本才能获得所需的结果

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;

感谢各位的工作,但当我嵌入我的查询时,我没有注意到。我注意到数据库中的数据似乎有一个回车,并存储如下所示,我们可以处理回车吗?PSN(此处回车)932-52656855-4780080712(此处回车)CSN/SF-7/25JAN0604抱歉,我不确定如何将replace函数嵌入下面的查询{SELECT REGEXP_SUBSTR('MYColumn','-(\w+)CSN',1,1,'i',1)“REGEXP_SUBSTR”FROM MYTABLE;}如果你需要在一个字符串中得到一个CR,你想要保留它还是移除它?不会有一个,但是如果你需要考虑它,那么它可以被移除。嘿,不用担心,我已经算了出来了。谢谢大家,这些工作,但不是当我嵌入到我的查询中时。我注意到数据库中的数据看起来有一个CARRI。年龄返回和存储如下所示,我们可以处理回车吗?PSN(此处回车)932-52656855-4780080712(此处回车)CSN/SF-7/25JAN0604抱歉,我不确定如何将替换函数嵌入下面的查询{从MYTABLE中选择REGEXP_SUBSTR('MYColumn','-(\w+)CSN',1,1,'i',1)“REGEXP u SUBSTR如果你有一个CR在字符串的一部分,你必须得到?你想保持它或删除?永远不会有一个,但如果你需要考虑这一点,那么它可以被删除。嘿,不用担心,我已经解决了它。