2016-12-26 105 views
0

我有數據,在一列的Oracle SQL正則表達式提取

+----------------------+ 
|  my_column  | 
+----------------------+ 
| test_PC_xyz_blah  | 
| test_PC_pqrs_bloh | 
| test_Mobile_pqrs_bleh| 
+----------------------+ 

我如何可以提取以下爲列如下?

+----------+-------+ 
| Platform | Value | 
+----------+-------+ 
| PC  | xyz | 
| PC  | pqrs | 
| Mobile | pqrs | 
+----------+-------+ 

我嘗試使用REGEXP_SUBSTR

默認第一圖案發生了platform

select regexp_substr(my_column, 'test_(.*)_(.*)_(.*)') as platform from table 

獲得第二圖案發生了value

select regexp_substr(my_column, 'test_(.*)_(.*)_(.*)', 1, 2) as value from table 

這不是工作,但是。我哪裏錯了?

回答

2

非空標記

select regexp_substr(my_column,'[^_]+',1,2) as platform 
     ,regexp_substr(my_column,'[^_]+',1,3) as value 

from my_table 
; 

對於可能爲空令牌

select regexp_substr(my_column,'^.*?_(.*)?_.*?_.*$',1,1,'',1) as platform 
     ,regexp_substr(my_column,'^.*?_.*?_(.*)?_.*$',1,1,'',1) as value 

from my_table 
; 

+----------+-------+ 
| PLATFORM | VALUE | 
+----------+-------+ 
| PC  | xyz | 
+----------+-------+ 
| PC  | pqrs | 
+----------+-------+ 
| Mobile | pqrs | 
+----------+-------+ 
0

(.*)本質上是貪婪的,它會匹配所有的字符,包括_字符一個所以test_(.*)將匹配整個你的字符串。因此_(.*)_(.*)模式中的其他組沒有任何匹配,整個正則表達式失敗。訣竅是匹配除_之外的所有字符。這可以通過定義組([^_]+)來完成。該組定義了一個否定字符集,它將匹配除_以外的任何字符。如果你有更好的模式,你可以使用它們,如[A-Za-z][:alphanum]。一旦你將你的字符串切分爲多個由_分隔的子字符串,那麼只需選擇第二和第三組。

例如:

SELECT REGEXP_SUBSTR(my_column,'(([^_]+))',1,2) as platform, REGEXP_SUBSTR(my_column,'(([^_]+))',1,3) as value from table;

注:據我所知,沒有直接的方法,以甲骨文精確匹配組。您可以使用regexp_replace來達到此目的,但它與其他編程語言的功能不同,您可以精確地確定組2和組3.請參閱this鏈接。