2016-07-05 177 views
1

我想用PL/SQL將一個分號分隔的字符串分成它的部分。只要字符串中沒有圓括號,它就可以和REGEXP_SUBSTR正常工作。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; 

這意味着「(」被檢測爲分隔符,但我不明白這種行爲。有人可以告訴我嗎?

回答

5

[]是一個Multilingual Regular Expression Syntax,它表示「用於指定匹配列表的括號表達式,該列表應該與列表中表示的任何一個表達式匹配。阿非匹配列表表達式開始於音調符號(^)並指定一個相匹配的任何字符以外的在列表中表示的表達式列表。」

例如

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

將返回A B(1) C其中[^";"]+認爲" OR ;作爲分隔符

同樣在你的榜樣[^(";")]+認爲";()爲s反對你的期望。

因此,對於你期望的輸出,你可以嘗試在我的肥皂箱

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

非常感謝,我明白了。 – user1838910

+0

@ user1838910如果您滿意,您可以接受此解決方案並關閉此問題 – SriniV

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> 

注意NULL返回元素2,符合市場預期。如果使用正則表達式格式'[^;]+',並試圖獲得第二個元素,你會得到'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是最後一個。想象一下所有不正確的報告。不要讓他們中的一個成爲你的!

+0

我知道這一點。替換'|'按'| '之前使用regexp_substr正在做我的情況的工作。儘管如此,謝謝你的提示。 – user1838910

+0

不知道你在說什麼,但是realspirituals值得投票,因爲他的回答對你的問題是正確的。礦是需要了解的其他信息。無論你做什麼,都要確保你測試了所有可能的意想不到的數據組合,並確保你的解決方案能處理所有這些數據! –