2016-12-26 124 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链接。