2

我想用 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;

预期的结果是:ABC

A;B(1);C 的结果应该是 AB(1) C 但我得到的是: AB 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;

这意味着 '(' 被检测为分隔符,但我不理解这种行为。有人可以赐教吗?

4

2 回答 2

5

[]是一种多语言正则表达式语法,它表示“用于指定匹配列表的括号表达式,该匹配列表应匹配列表中表示的任何一个表达式。不匹配的列表表达式以抑扬符 (^) 开头,并指定一个匹配任何字符的列表,除了列表中表示的表达式。”

例如

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

将返回A B(1) C将OR[^";"]+视为分隔符的地方";

同样,在您的示例中, [^(";")]+"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;
于 2016-07-05T15:02:54.087 回答
1

我再次爬上我的肥皂盒,警告人们使用格式的正则表达式'[^;]+'解析分隔字符串的危险。悔改并得救!它不处理 NULL 元素并且将返回意外结果。有关更多信息和证明,请参见此处。请改用此格式,并且知道您的输出准确无误:

注意第二个元素是(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,如预期的那样。如果您使用正则表达式格式'[^;]+'并尝试获取第二个元素,您将得到'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 是最后一个。想象一下所有不正确的报告。不要让其中之一成为你的!

于 2016-07-05T17:48:27.137 回答