REGEXP_SUBSTR 圆括号

REGEXP_SUBSTR round bracket

我想用 PL/SQL 将分号分隔的字符串分成多个部分。只要字符串中没有圆括号,REGEXP_SUBSTR 就可以正常工作。

示例:

select REGEXP_SUBSTR('A;B;C','[^(";")]+',1,1),
REGEXP_SUBSTR('A;B;C','[^(";")]+',1,2),
REGEXP_SUBSTR('A;B;C','[^(";")]+',1,3)
from dual;

预期的结果是:A B C

A;B(1);C 的结果应该是 A B(1) C 但我得到的是:A B 1

select REGEXP_SUBSTR('A;B(1);C','[^(";")]+',1,1),
REGEXP_SUBSTR('A;B(1);C','[^(";")]+',1,2),
REGEXP_SUBSTR('A;B(1);C','[^(";")]+',1,3)
from dual;

这意味着“(”被检测为分隔符,但我不明白这种行为。有人可以赐教吗?

[] 是一个 Multilingual Regular Expression Syntax 表示 "Bracket expression for specifying a matching list that should match any one of the expressions represented in the list. A nonmatching list expression begins with a circumflex (^) and specifies a list that matches any character except for the expressions represented in the list."

例如

select REGEXP_SUBSTR('"A";"B(1)";"C"','[^";"]+',1,1)
from dual;

将 return A B(1) C 其中 [^";"]+ 认为 "; 作为分隔符

与您的示例类似,[^(";")]+" OR ; OR ( OR ) 作为分隔符,这与您的期望不符。

因此,对于您预期的输出,您可以尝试

select REGEXP_SUBSTR('A;B(1);C','[^;]+',1,1),
REGEXP_SUBSTR('A;B(1);C','[^;]+',1,2),
REGEXP_SUBSTR('A;B(1);C','[^;]+',1,3)
from dual;

我再一次爬上我的肥皂盒来警告人们使用 '[^;]+' 格式的正则表达式来解析分隔字符串的危险。悔改得救!它不处理 NULL 元素,并且会 return 意想不到的结果。有关详细信息和证明,请参阅 。请改用此格式,并在知道您的输出是准确的情况下高枕无忧:

注意第二个元素是 (NULL)

SQL> with tbl(str) as (
      select 'A;;B(1);C' from dual
    )
    select regexp_substr(str, '(.*?)(;|$)', 1, level, NULL, 1)
    from tbl
    connect by level <= regexp_count(str, ';') + 1;

REGEXP_SU
---------
A

B(1)
C

SQL>

请注意元素 2 的 NULL returned,正如预期的那样。如果您使用正则表达式格式 '[^;]+' 并尝试获取第二个元素,您将得到 'B(1)' 这是不正确的,因为它是第三个元素:

不要使用:

SQL> with tbl(str) as (
  2    select 'A;;B(1);C' from dual
  3  )
  4  select regexp_substr(str, '[^;]+', 1, level)
  5  from tbl
  6  connect by level <= regexp_count(str, ';') + 1;

REGEXP_SU
---------
A
B(1)
C


SQL>

仔细看,NULL在最后。想象一下所有不正确的报告。不要让其中之一成为你的!