从Oracle中的字符串中提取子字符串

时间:2018-01-24 15:02:16

标签: sql regex oracle

我需要从字符串中提取子字符串,其中space是分隔符()。 对于我使用的相同:

select
REGEXP_SUBSTR('mobile Motorola Nexus 6','[^ ]+',1,1) A,
REGEXP_SUBSTR('mobile Motorola Nexus 6','[^ ]+',1,2) B,
REGEXP_SUBSTR('mobile Motorola Nexus 6','[^ ]+',1,3) C
from dual;
输出为

A          B        C
mobile  Motorola    Nexus

但我要求的输出是:

A          B        C
mobile  Motorola    Nexus 6

3 个答案:

答案 0 :(得分:1)

假设上面是唯一需要输出的模式,一种方法是使用以下内容修改正则表达式:

select
REGEXP_SUBSTR('mobile Motorola Nexus 6','(\w){1,}( \d){0,}',1,1) A,
REGEXP_SUBSTR('mobile Motorola Nexus 6','(\w){1,}( \d){0,}',1,2) B,
REGEXP_SUBSTR('mobile Motorola Nexus 6','(\w){1,}( \d){0,}',1,3) C
from dual;

<强>输出:

A      B        C
------ -------- -------
mobile Motorola Nexus 6

答案 1 :(得分:1)

在评论中,OP澄清了所需的子字符串是:直到第一个空格的子字符串,第一个和第二个空格之间的子字符串,以及从第二个空格到输入字符串末尾的子字符串。并且空格是单个空格(一行中有两个空格,然后将空子字符串标记为相应的值)。

如果是这样,并且如果已知每个输入字符串将包含至少两个空格,则可以通过使用标准字符串函数有效地解决问题(比使用正则表达式更快)。在下面的演示中,我在with子句中创建输入数据,但这不是解决方案的一部分;实际的SQL查询从select .....开始。

with
  inputs ( str ) as (
    select 'mobile Motorola Nexus 6' from dual
  )
select substr(str, 1, instr(str, ' ') - 1)                         as a,
       substr(str, instr(str, ' ') + 1,
                      instr(str, ' ', 1, 2) - instr(str, ' ') - 1) as b,
       substr(str, instr(str, ' ', 1, 2) + 1)                      as c
from   inputs
;

A      B        C     
------ -------- -------
mobile Motorola Nexus 6

正则表达式效率较低,但它们允许代码更紧凑 - 并且它们允许更大的灵活性(如果需求在将来发生变化 - 例如允许一个或更多连续空格到是一个单一的分隔符。)

select regexp_substr(str, '([^ ]*) '       , 1, 1, null, 1) as a,
       regexp_substr(str, '([^ ]*) '       , 1, 2, null, 1) as b,
       regexp_substr(str, '([^ ]* ){2}(.*)', 1, 1, null, 2) as c
from   inputs
;

请注意c的计算:我们读取过去前两次出现(零个或多个非空格后跟一个空格),然后我们捕获 rest < / strong>的字符串,直到最后。这与前两个令牌(ab)不同。

另外 - 与OP的尝试不同,后者寻找一个或更多连续非空格的出现 - 我在这里提供的两个解决方案都会查找出现零< / strong>或更多连续的非空格,允许连续两个空格表示空子字符串(与Oracle中的null相同)。

答案 2 :(得分:-1)

假设名称永远不会以数字开头,您可以使用REGEXP_REPLACE删除数字前面的空格:

mailitem.onclose(olDiscard)