2011-07-07 38 views
5

據我所知,MySQL不支持從正則表達式匹配中獲取捕獲組的值。我找到了一個服務器端擴展(lib_mysqludf_preg),它可以添加此功能,但我無法在我的環境中安裝此擴展。模擬mysql中的正則表達式捕獲組

所以,我正在尋找一種方法來模擬捕獲正則表達式匹配的一部分作爲SQL查詢中的一列。

我的數據如下所示(我不能更改服務器上的數據格式):我正在尋找捕捉每一個從各行的最後4位數字

+-----------------------------+ 
| Version      | 
+-----------------------------+ 
| 1.2.3.4      | 
| 10.20.30.40     | 
| Obsidian-1.2.3.4   | 
| Obsidian-11.21.31.41  | 
| custom\Obsidian-11.21.31.41 | 
| custom\11.21.31.41   | 
+-----------------------------+ 

。數字總是數值的最後部分,並且它們總是用點分隔。下面的正則表達式會匹配所有我想要的值:

.*[[:digit:]]+\\.[[:digit:]]+\\.[[:digit:]]+\\.[[:digit:]]+$ 

我希望的結果是某些功能的組合來捕捉每個數字爲一列,這樣我可以在where子句中使用數字我的查詢以及能夠返回版本號。

SELECT 
    function1(...) as version1, 
    function2(...) as version2, 
    function3(...) as version3, 
    function4(...) as version4 
FROM Version 
WHERE version1 > 5; 
+0

爲什麼不只是用您選擇的編程語言來做到這一點? – Qtax

+1

至少你可以用SUBSTRING_INDEX(ver,'。',-1)很容易地得到最後一個數字作爲version4'。其他人可能通過混淆[MySQLs string functions](http://dev.mysql.com/doc/refman/5.5/en/string-functions.html)。不知道沒有安裝擴展程序是否有更好的方法。 – Qtax

回答

3

經過一些試驗和錯誤,我想出了以下查詢,做我所需要的。基本上,我分開字符串的末尾分開的數字,然後刪除多個字符,然後分離下一個數字。版本1專欄僅限於正數2位數字,但這是我可以忍受的限制。

SELECT 
    IF(CAST(RIGHT(SUBSTRING_INDEX(LEFT(version,CHAR_LENGTH(version) - CHAR_LENGTH(SUBSTRING_INDEX(version, '.', -3)) - 1), '.', -1),2) AS DECIMAL) > 0, 
     CAST(RIGHT(SUBSTRING_INDEX(LEFT(version,CHAR_LENGTH(version) - CHAR_LENGTH(SUBSTRING_INDEX(version, '.', -3)) - 1), '.', -1),2) AS DECIMAL), 
     CAST(RIGHT(SUBSTRING_INDEX(LEFT(version,CHAR_LENGTH(version) - CHAR_LENGTH(SUBSTRING_INDEX(version, '.', -3)) - 1), '.', -1),1) AS DECIMAL)) AS version1, 
    SUBSTRING_INDEX(LEFT(version,CHAR_LENGTH(version) - CHAR_LENGTH(SUBSTRING_INDEX(version, '.', -2)) - 1), '.', -1) as version2, 
    SUBSTRING_INDEX(LEFT(version,CHAR_LENGTH(version) - CHAR_LENGTH(SUBSTRING_INDEX(version, '.', -1)) - 1), '.', -1) as version3, 
    SUBSTRING_INDEX(version, '.', -1) as version4 
FROM Version 
HAVING version1 >= 5 
;