Oracle REGEXP_SUBSTR 忽略字符的第一次出现但包括第二次出现
Oracle REGEXP_SUBSTR to ignore the first ocurrence of a character but include the 2nd occurence
我有一个格式为“数字 - 名称”的字符串,我正在使用 REGEXP_SUBSTR 将它分成两个单独的列,一列用于名称,一列用于数字。
SELECT
REGEXP_SUBSTR('123 - ABC','[^-]+',1,1) AS NUM,
REGEXP_SUBSTR('123 - ABC','[^-]+',1,2) AS NAME
from dual;
但如果名称包含连字符,则它不起作用,例如:ABC-Corp,那么名称将只显示为 'ABC' 而不是 'ABC-Corp'。我怎样才能让正则表达式 exp 忽略第一个 hypen 之前的所有内容并包含它之后的所有内容?
您想在第一次出现 ' - '
时拆分字符串。这是一个足够简单的任务,可以由字符串函数而不是正则表达式有效地执行:
select
substr(mycol, 1, instr(mycol, ' - ') - 1) num,
substr(mycol, instr(mycol, ' - ') + 3) name
from mytable
with mytable as (
select '123 - ABC' mycol from dual
union all select '123 - ABC - Corp' from dual
)
select
mycol,
substr(mycol, 1, instr(mycol, ' - ') - 1) num,
substr(mycol, instr(mycol, ' - ') + 3) name
from mytable
MYCOL | NUM | NAME
:--------------- | :-- | :---------
123 - ABC | 123 | ABC
123 - ABC - Corp | 123 | ABC - Corp
NB: @GMB 解决方案在您的简单情况下要好得多。为此使用正则表达式有点矫枉过正。
tldr;
通常在这种固定掩码的情况下,使用 subexpr
参数而不是 occurrence
更容易和更易读。所以你可以指定完整的掩码:\d+\s*-\s*\S+
即数字,然后是 0 个或更多空白字符,然后是 -,再次是 0 个或更多空白字符和 1+ non-whitespace 个字符。
然后我们添加 () 来指定子表达式:因为我们只需要数字和尾随 non-whitespace 字符,我们将它们放入 ():
'(\d+)\s*-\s*(\S+)'
然后我们只需要指定我们需要的子表达式,1 或 2:
SELECT
REGEXP_SUBSTR(column_value,'(\d+)\s*-\s*(\S+)',1,1,null,1) AS NUM,
REGEXP_SUBSTR(column_value,'(\d+)\s*-\s*(\S+)',1,1,null,2) AS NAME
from table(sys.odcivarchar2list('123 - ABC', '123 - ABC-Corp'));
结果:
NUM NAME
---------- ----------
123 ABC
123 ABC-Corp
https://docs.oracle.com/database/121/SQLRF/functions164.htm#SQLRF06303
https://docs.oracle.com/database/121/SQLRF/ap_posix003.htm#SQLRF55544
我有一个格式为“数字 - 名称”的字符串,我正在使用 REGEXP_SUBSTR 将它分成两个单独的列,一列用于名称,一列用于数字。
SELECT
REGEXP_SUBSTR('123 - ABC','[^-]+',1,1) AS NUM,
REGEXP_SUBSTR('123 - ABC','[^-]+',1,2) AS NAME
from dual;
但如果名称包含连字符,则它不起作用,例如:ABC-Corp,那么名称将只显示为 'ABC' 而不是 'ABC-Corp'。我怎样才能让正则表达式 exp 忽略第一个 hypen 之前的所有内容并包含它之后的所有内容?
您想在第一次出现 ' - '
时拆分字符串。这是一个足够简单的任务,可以由字符串函数而不是正则表达式有效地执行:
select
substr(mycol, 1, instr(mycol, ' - ') - 1) num,
substr(mycol, instr(mycol, ' - ') + 3) name
from mytable
with mytable as (
select '123 - ABC' mycol from dual
union all select '123 - ABC - Corp' from dual
)
select
mycol,
substr(mycol, 1, instr(mycol, ' - ') - 1) num,
substr(mycol, instr(mycol, ' - ') + 3) name
from mytable
MYCOL | NUM | NAME :--------------- | :-- | :--------- 123 - ABC | 123 | ABC 123 - ABC - Corp | 123 | ABC - Corp
NB: @GMB 解决方案在您的简单情况下要好得多。为此使用正则表达式有点矫枉过正。
tldr;
通常在这种固定掩码的情况下,使用 subexpr
参数而不是 occurrence
更容易和更易读。所以你可以指定完整的掩码:\d+\s*-\s*\S+
即数字,然后是 0 个或更多空白字符,然后是 -,再次是 0 个或更多空白字符和 1+ non-whitespace 个字符。
然后我们添加 () 来指定子表达式:因为我们只需要数字和尾随 non-whitespace 字符,我们将它们放入 ():
'(\d+)\s*-\s*(\S+)'
然后我们只需要指定我们需要的子表达式,1 或 2:
SELECT
REGEXP_SUBSTR(column_value,'(\d+)\s*-\s*(\S+)',1,1,null,1) AS NUM,
REGEXP_SUBSTR(column_value,'(\d+)\s*-\s*(\S+)',1,1,null,2) AS NAME
from table(sys.odcivarchar2list('123 - ABC', '123 - ABC-Corp'));
结果:
NUM NAME
---------- ----------
123 ABC
123 ABC-Corp
https://docs.oracle.com/database/121/SQLRF/functions164.htm#SQLRF06303
https://docs.oracle.com/database/121/SQLRF/ap_posix003.htm#SQLRF55544