我想用分号分隔的字符串用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;
这意味着'('被检测为分隔符,但我不明白这种行为。有人可以赐教我吗?
答案 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是最后的。想象一下所有不正确的报告。不要让他们中的一个成为你的!