【问题标题】:REGEXP_SUBSTR round bracketREGEXP_SUBSTR 圆括号
【发布时间】:2016-11-07 11:32:49
【问题描述】:

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

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

【问题讨论】:

    标签: regex oracle plsql regexp-substr


    【解决方案1】:

    [] 是一个Multilingual Regular Expression Syntax,它表示“用于指定匹配列表的括号表达式,该列表应匹配列表中表示的任何一个表达式。非匹配列表表达式以抑扬符 (^) 开头并指定一个列表匹配除列表中表示的表达式之外的任何字符。"

    例如

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

    将返回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;
    

    【讨论】:

    • 非常感谢,我知道了。
    • @user1838910 您可以接受此作为解决方案,如果您满意,请关闭此问题
    【解决方案2】:

    我再次爬上我的肥皂盒,警告人们使用 '[^;]+' 格式的正则表达式解析分隔字符串的危险。悔改并得救!它不处理 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 是最后一个。想象一下所有不正确的报告。不要让其中一个成为你的!

    【讨论】:

    • 我知道这一点。替换“|”通过'| ' 在我使用 regexp_substr 之前正在做这项工作。不过感谢您的提示。
    • 不确定您在说什么,但 realspirituals 值得投票,因为他的回答是您问题的正确答案。我的是需要注意的其他信息。无论您做什么,请确保使用您能想到的所有可能的意外数据组合进行测试,并确保您的解决方案能够处理所有这些!
    猜你喜欢
    • 1970-01-01
    • 2020-06-14
    • 1970-01-01
    • 2013-05-18
    • 2011-01-12
    • 2021-10-12
    • 1970-01-01
    • 2021-01-11
    相关资源
    最近更新 更多