2012-11-06 57 views
1

我試圖使用Oracle的REGEXP_SUBSTR()函數從文本字段中提取分鐘數。正則表達式if-else表達式

數據:

Treatment of PC7, PT1 on left. 15 min. 
15 minutes. 
15 minutes 
15 mins. 
15 mins 
15 min. 
15 min 
15min 
15 

在每一種情況下,我希望能提取字符串的 '15' 的一部分。

嘗試:

  • \d+得到所有的數值,包括 '7' 和 '1',這是不希望的。
  • (\d)+(?=\ ?min)從除最後一行以外的所有行中獲得'15'。
  • (?((\d)+(?=\ ?min))((\d)+(?=\ ?min))|\d+),一個條件語句,不匹配任何東西。

我的條件聲明有什麼問題?

**編輯**

WITH DATA AS (

    SELECT 'Treatment of PC7, PT1 on left. 15 min.' COMMENTS FROM DUAL 

    UNION ALL 

    SELECT '15 minutes.' COMMENTS FROM DUAL 

    UNION ALL 

    SELECT '15 minutes' COMMENTS FROM DUAL 

    UNION ALL 

    SELECT '15 mins.' COMMENTS FROM DUAL 

    UNION ALL 

    SELECT '15 mins' COMMENTS FROM DUAL 

    UNION ALL 

    SELECT '15 min.' COMMENTS FROM DUAL 

    UNION ALL 

    SELECT '15 min' COMMENTS FROM DUAL 

    UNION ALL 

    SELECT '15min' COMMENTS FROM DUAL 

    UNION ALL 

    SELECT '15' COMMENTS FROM DUAL 

) 

SELECT COMMENTS, 
     REGEXP_SUBSTR(COMMENTS, '(\d+)\s?(?:min.*)?$', 1, 1) A, 
     REGEXP_SUBSTR(COMMENTS, '\d+?(?= ?min)|^\d+$', 1, 1) B, 
     REGEXP_SUBSTR(COMMENTS, '\d+?(?: ?min)|^\d+$', 1, 1) C 

FROM DATA 

結果(必須有一個更好的方式來設置列格式不是 '代碼示例'):

COMMENTS A B C 
Treatment of PC7, PT1 on left. 15 min.   
15 minutes.   
15 minutes   
15 mins.    
15 mins   
15 min.   
15 min   
15min   
15 15 15 15 
+0

我看不出有任何的if-else語句。向我們展示實際的代碼,而不是總結。 –

+0

Oracle的regexp函數是否支持條件構造? – Xophmeister

+0

@AndyLester,最後一個要點是'if-else'表達式,至少根據http://www.regular-expressions.info/conditional.html。 – craig

回答

3

這個表達式會爲你工作。

^.*?(\d+)((?min.*$)|$) 

說明

  • ^.*? - 的字符串的開頭,後跟任意字符匹配0次或多次
  • (\d+) - 匹配至少一個數位,並將其存儲在反向引用位置1
  • (?min.*$) - 匹配空格(可能),min,任何字符(可能),然後是字符串的結尾。
  • (...|$) - 如果它找不到min,它會看到是否有字符串的結尾。

然後,而不是使用REGEXP_SUBSTR(),使用REGEXP_REPLACE()這樣,更換什麼是存儲在反向引用位置1(你的電話號碼),整個字符串:

REGEXP_REPLACE(COMMENTS, '^.*?(\d+)((?min.*$)|$)', '\1') A 
+0

我在http://regexpal.com上試過你的表情;它適用於所有情況,但最後的'15'。甲骨文根本不喜歡這個表達。 – craig

+0

@craig - 我的印象是,這個字符串只會是其中的一個。所以如果被測試的字符串只是'15',它就會匹配。你是否試圖一次匹配所有的東西? – Aust

+0

是的,它只會是其中之一。我糾正了我的測試,並且它在regexpal上工作。我將不得不研究Oracle是否支持條件。 – craig

1

如果你能保證時間戳總會出現字符串的最後一部分,這個工程:

(\d+)\s?(?:min.*)?$ 

我不知道,如果Oracle支持非捕獲組,但是這很容易合作周圍。我的經驗是,它的RegExp引擎僅限於相當香草的東西。

+0

+1 - 我同意。如果確保時間戳結束,那就更好了。 – Aust

+0

不保證。 – craig

0

替代,工作的解決方案,採用了多種表情:

TO_NUMBER(
    CASE 
     -- number only 
     WHEN LENGTH(REGEXP_SUBSTR(MEAS_COMMENT, '^\d+$', 1, 1)) >0 THEN REGEXP_SUBSTR(MEAS_COMMENT, '^\d+$', 1, 1) 
     -- XX min 
     WHEN LENGTH(REGEXP_SUBSTR(MEAS_COMMENT, '\d+(?min)', 1, 1)) >0 THEN REGEXP_SUBSTR(REGEXP_SUBSTR(MEAS_COMMENT, '\d+(?min)', 1, 1), '\d+', 1, 1) 
    END 
) MINUTES 

**編輯**

-- same results without the `CASE` statement: 
TO_NUMBER(REGEXP_SUBSTR(REGEXP_SUBSTR(COMMENTS, '(\d+)(?min|$)', 1, 1), '\d+', 1, 1))