2015-06-28 46 views
1

我遇到以下問題。 有一個字符串:PLSQL顯示字符串末尾的數字

There is something 2015.06.06. in the air 1234567 242424 2015.06.07. 12125235

我需要證明纔剛剛從這個字符串的最後日期:2015.06.07。 我嘗試regexp_substrinsrt,但它不起作用。 所以這只是測試,如果我可以解決這個問題後,這個解決方案我應該使用它的CLOB查詢有多個日期,我只需要最後一個。我知道有regexp_count,這是幫助解決這個問題,但我使用的數據庫是Oracle 10g,所以它不會工作。

有人可以幫我嗎?

+0

你能發表你試過的正則表達式嗎?這將爲回答這個問題提供一個更好的起點。 – vallismortis

+0

select substr('There is something 2015.06.06。in the air 1234567 242424 2015.06.07。12125235',instr('There was something 2015.06.06。in the air 1234567 242424 2015.06.07。12125235',1,-1 )-instr('There is something 2015.06.06。in the air 1234567 242424 2015.06.07。12125235',regexp_substr('There was something 2015.06.06。in the air 1234567 242424 2015.06.07。12125235','\ d \ d,d,d,d,d,d),1), - 1,1),10) – Cafu90

回答

2

找到解決此問題的關鍵是反轉this answer中提供的字符串中的單詞的想法。

以下是可能的解決方案:

WITH words AS 
(
SELECT regexp_substr(str, '[^[:space:]]+', 1, LEVEL) word, 
     rownum rn 
    FROM (SELECT 'There is something 2015.06.06. in the air 1234567 242424 2015.06.07. 2015.06.08 2015.06.17. 2015.07.01. 12345678999 12125235' str 
      FROM dual) tab 
CONNECT BY LEVEL <= LENGTH(str) - LENGTH(REPLACE(str, ' ')) + 1 
) 
, words_reversed AS 
(
SELECT * 
    FROM words 
ORDER BY rn DESC 
) 
SELECT regexp_substr(word, '\d{4}\.\d{2}\.\d{2}', 1, 1) 
    FROM words_reversed 
WHERE regexp_like(word, '\d{4}\.\d{2}\.\d{2}') 
    AND rownum = 1; 
+0

是的,這是一般的想法,但我更多地思考[扭轉整個字符串](https://community.oracle.com/thread/73109?start = 0&tstart = 0)並反轉正則表達式,然後再次反轉結果。 – vallismortis

+0

非常感謝你,它完美的作品。所以就像我寫的那樣,我嘗試了instr,並且它沒有工作。你的解決方案完美地工作,但我對短一點感興趣。有可能在regexp_substr中給出從字符串末尾檢查的內容嗎?否則,謝謝你們兩位的幫助。 – Cafu90

1

從上regexp_substr的文檔,我立刻看到一個問題:

.(期)的任何字符匹配。您需要使用反斜槓:\.來避開它們,以便僅匹配句點字符。

作爲參考,我鏈接了this post,這似乎是您採取的方法與substrinstr

Relevant documentation從Oracle:

INSTR(string , substring [, position [, occurrence]])

當位置爲負,則INSTR計數和從字符串的末尾向後搜索。位置的默認值是1,這意味着函數在字符串的開始處開始搜索。

這裏的問題是,你的正則表達式只返回一個值,如解釋here,所以你會被給予instr功能在多個日期的情況下,合適的匹配。

現在,由於這個限制,我推薦使用在this question中提出的方法,即顛倒整個字符串(和您的正則表達式,即\d{2}\.\d{2}\.\d{4}),然後第一個匹配成爲'最後匹配'。然後,執行另一個字符串反轉以獲取原始日期格式。

也許這不是最好的解決方案,但它應該工作。

+0

嗨,我試圖做你的建議,但它不能使用它。所以首先,我只需要regexp_substr子句,然後我可以解決它,但我嘗試了很多方法,它不會工作。這是我的代碼:select instr('There is something 2015.06.06。in the air 1234567 242424 2015.06.07。2015.06.08 2015.06.17。2015.07.01。12345678999 12125235',regexp_substr('There was something 2015.06.06。in空氣1234567 242424 2015.06.07。2015.06.08 2015.06.17。2015.07.01。12345678999 12125235','\ d \ d \ d \ d \ d \ d \ d \ d \ d',1), - 1,1)作爲雙重fasz; – Cafu90

1

有三種不同的PL/SQL功能,將讓你在那裏。

  1. INSTR函數將識別日期字符串中第一個「句點」出現的位置。
  2. SUBSTR施加到整個字符串使用值從(1)爲起點
  3. TO_DATE特定日期掩模:YYYY.MM.DD將從(2)轉換成Oracle日期時間類型的結果進行轉換。

要在程序代碼這項工作中,標準塊適用於:

DECLARE 
    v_position pls_integer; 
    ... other variables 
BEGIN 
    sql code and function calls; 

END 

SQL Fiddle

的Oracle 11g R2架構設置

CREATE TABLE finddate 
    (column1 varchar2(11), column2 varchar2(39)) 
; 

INSERT ALL 
    INTO finddate (column1, column2) 
     VALUES ('row1', '1234567 242424 2015.06.07. 12125235') 
    INTO finddate (column1, column2) 
     VALUES ('string2', '1234567 242424 2015.06.07. 12125235') 
SELECT * FROM dual 
; 

查詢1

select instr(column2,'.',1) from finddate 
where column1 = 'string2' 

select substr(column2,(20-4),10) from finddate 

select to_date('2015.06.07','YYYY.MM.DD') from finddate 

Results

| TO_DATE('2015.06.07','YYYY.MM.DD') | 
|------------------------------------| 
|    June, 07 2015 00:00:00 | 
|    June, 07 2015 00:00:00 | 
+0

非常感謝。 IT非常有幫助。最好的regerds。 – Cafu90

1

下面是使用regexp_replace()的方式,應該按10g工作,假設行的格式將是相同的:

with tbl(col_string) as 
(
    select 'There is something 2015.06.06. in the air 1234567 242424 2015.06.07. 12125235' 
    from dual 
) 
select regexp_replace(col_string, '^.*(\d{4}\.\d{2}\.\d{2})\. \d*$', '\1') 
from tbl; 

正則表達式可以被解讀爲:

^ - Match the start of the line 
. - followed by any character 
* - followed by 0 or more of the previous character (which is any character) 
( - Start a remembered group 
\d{4}\.\d{2}\.\d{2} - 4 digits followed by a literal period followed by 2 digits, etc 
) - End the first remembered group 
\. - followed by a literal period 
    - followed by a space 
\d* - followed by any number of digits 
$ - followed by the end of the line 

regexp_replace然後用第一個記憶組(\ 1)替換所有。

基本上將整行描述爲一個正則表達式,圍繞您想要返回的組進行分組。如果可能是其他字符而不是數字,你很可能需要調整行尾的正則表達式,但這應該會給你一個想法。

對於參數的緣故這部作品太ONLY IF有2次出現的日期模式:

with tbl(col_string) as 
(
    select 'There is something 2015.06.06. in the air 1234567 242424 2015.06.07. 12125235' from dual 
) 
select regexp_substr(col_string, '\d{4}\.\d{2}\.\d{2}', 1, 2) 
from tbl; 

返回模式的第二次出現。我期望上面的regexp_replace更準確地描述解決方案。

+0

非常感謝你。 IT非常有幫助。 – Cafu90