REGEXP_SUBSTR圆括号

时间:2016-07-05 14:56:40

标签: regex oracle plsql regexp-substr

我想用分号分隔的字符串用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;

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

2 个答案:

答案 0 :(得分:5)

[]Multilingual Regular Expression Syntax,其中显示“用于指定匹配列表的括号表达式,该匹配列表应与列表中表示的任何一个表达式匹配。不匹配列表表达式以回旋符号(^)开头,指定一个列表,该列表匹配除列表中表示的表达式之外的任何字符。“

例如

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

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

同样在您的示例中,[^(";")]+会将";()视为您期望的分隔符。

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

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;

答案 1 :(得分:1)

我再一次爬上我的肥皂盒,警告人们使用格式'[^;]+'的正则表达式解析分隔字符串的危险。悔改并得救!它不处理NULL元素并且会返回意外结果。有关详细信息和证明,请参阅here。请使用此格式,让您轻松了解输出是否准确:

注意第二个元素是(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是最后的。想象一下所有不正确的报告。不要让他们中的一个成为你的!