正则表达式聚合捕获组
regex aggregate capturing groups
我有一个数据样本 http://sqlfiddle.com/#!4/ecba5/4:
with raw_data as(select
'a{ thing_a<1234:1.1>>thing_b<->>thing_c<T>>thing_d<F>>thing_f<F>>thing_g<F>>thing_h<F>>thing_i<F>>thing_x<F>>thing_y<F>>thing_z<F>>#thing_a<234:1.2>>thing_b<->>thing_c<T>>thing_d<F>>thing_f<F>>thing_g<F>>thing_h<F>>thing_i<F>>thing_x<T>>thing_y<F>>thing_z<F>>#thing_a<345:1.3>>thing_b<->>thing_c<T>>thing_d<F>>thing_f<F>>thing_g<F>>thing_h<F>>thing_i<F>>thing_x<T>>thing_y<F>>thing_z<F>>#thing_a<456:1.4>>thing_b<->>thing_c<T>>thing_d<F>>thing_f<F>>thing_g<F>>thing_h<F>>thing_i<F>>thing_x<T>>thing_y<F>>thing_z<F>>#};ADD{some_thing<1234>>some_id<null>>some_stuff<2>>some_date<2013-07-09+02:00>>thing_zz<1>>foo_bar<0>>status_foo<0>>bar_value<0>>#some_thing<234>>some_id<null>>some_stuff<2>>some_date<2013-10-21+02:00>>thing_zz<1>>foo_bar<0>>status_foo<0>>bar_value<0>>#some_thing<345>>some_id<null>>some_stuff<2>>some_date<2013-07-22+02:00>>thing_zz<1>>foo_bar<0>>status_foo<0>>bar_value<0>>#some_thing<456>>some_id<null>>some_stuff<1>>some_date<2014-03-31+02:00>>thing_zz<1>>foo_bar<0>>status_foo<0>>bar_value<0>>#}]' value
from dual)
select
regexp_count(value, 'thing_a<\d*:\d\.\d*>') thing_a, -- count all occurences of thing_a
regexp_replace(value, 'thing_b<(-)>', '0'), -- How to only replace capturing group?
--regexp_substr(regexp_replace(value, 'thing_b<(-)>', '0'),'thing_b<(.)>', 1, 1, NULL, 1), -- assuming this works - how to sum it up? there is no regexp_sum to aggregate the capturing groups?
value
from raw_data;
一些聚合很容易,即对于 thing_a
,regexp_count
工作正常。但是,对于所有其他人,例如 thing_b
,首先将 -
替换为 NaN
,将 F
替换为 0
,将 T
替换为 1
每个捕获组都应该发生。
然后我想总结一下。但是 regexp_sum
似乎不存在。
所需的输出类似于:
thing_a,thing_b,thing_d,...,thing_x
4,0,0,...,3
您可以通过将整个匹配替换为删除捕获组的重新格式化的版本来实现此目的:
regexp_replace(value, '(thing_b)<(-)>', '<0>')
可以使用 Oracle 的内置 SUM() 对这些值求和:
sum(to_number(regexp_substr(regexp_replace(value, '(thing_b)<(-)>', '<0>'),'thing_b<(.)>', 1, 1, NULL, 1)))
完整查询:
with raw_data as(select
'a{ thing_a<1234:1.1>>thing_b<->>thing_c<T>>thing_d<F>>thing_f<F>>thing_g<F>>thing_h<F>>thing_i<F>>thing_x<F>>thing_y<F>>thing_z<F>>#thing_a<234:1.2>>thing_b<->>thing_c<T>>thing_d<F>>thing_f<F>>thing_g<F>>thing_h<F>>thing_i<F>>thing_x<T>>thing_y<F>>thing_z<F>>#thing_a<345:1.3>>thing_b<->>thing_c<T>>thing_d<F>>thing_f<F>>thing_g<F>>thing_h<F>>thing_i<F>>thing_x<T>>thing_y<F>>thing_z<F>>#thing_a<456:1.4>>thing_b<->>thing_c<T>>thing_d<F>>thing_f<F>>thing_g<F>>thing_h<F>>thing_i<F>>thing_x<T>>thing_y<F>>thing_z<F>>#};ADD{some_thing<1234>>some_id<null>>some_stuff<2>>some_date<2013-07-09+02:00>>thing_zz<1>>foo_bar<0>>status_foo<0>>bar_value<0>>#some_thing<234>>some_id<null>>some_stuff<2>>some_date<2013-10-21+02:00>>thing_zz<1>>foo_bar<0>>status_foo<0>>bar_value<0>>#some_thing<345>>some_id<null>>some_stuff<2>>some_date<2013-07-22+02:00>>thing_zz<1>>foo_bar<0>>status_foo<0>>bar_value<0>>#some_thing<456>>some_id<null>>some_stuff<1>>some_date<2014-03-31+02:00>>thing_zz<1>>foo_bar<0>>status_foo<0>>bar_value<0>>#}]' value
from dual)
select
regexp_count(value, 'thing_a<\d*:\d\.\d*>') thing_a, -- count all occurences of thing_a
regexp_replace(value, '(thing_b)<(-)>', '<0>'), -- How to only replace capturing group?
sum(to_number(regexp_substr(regexp_replace(value, '(thing_b)<(-)>', '<0>'),'thing_b<(.)>', 1, 1, NULL, 1))) -- assuming this works - how to sum it up? there is no regexp_sum to aggregate the capturing groups?
from raw_data;
我有一个数据样本 http://sqlfiddle.com/#!4/ecba5/4:
with raw_data as(select
'a{ thing_a<1234:1.1>>thing_b<->>thing_c<T>>thing_d<F>>thing_f<F>>thing_g<F>>thing_h<F>>thing_i<F>>thing_x<F>>thing_y<F>>thing_z<F>>#thing_a<234:1.2>>thing_b<->>thing_c<T>>thing_d<F>>thing_f<F>>thing_g<F>>thing_h<F>>thing_i<F>>thing_x<T>>thing_y<F>>thing_z<F>>#thing_a<345:1.3>>thing_b<->>thing_c<T>>thing_d<F>>thing_f<F>>thing_g<F>>thing_h<F>>thing_i<F>>thing_x<T>>thing_y<F>>thing_z<F>>#thing_a<456:1.4>>thing_b<->>thing_c<T>>thing_d<F>>thing_f<F>>thing_g<F>>thing_h<F>>thing_i<F>>thing_x<T>>thing_y<F>>thing_z<F>>#};ADD{some_thing<1234>>some_id<null>>some_stuff<2>>some_date<2013-07-09+02:00>>thing_zz<1>>foo_bar<0>>status_foo<0>>bar_value<0>>#some_thing<234>>some_id<null>>some_stuff<2>>some_date<2013-10-21+02:00>>thing_zz<1>>foo_bar<0>>status_foo<0>>bar_value<0>>#some_thing<345>>some_id<null>>some_stuff<2>>some_date<2013-07-22+02:00>>thing_zz<1>>foo_bar<0>>status_foo<0>>bar_value<0>>#some_thing<456>>some_id<null>>some_stuff<1>>some_date<2014-03-31+02:00>>thing_zz<1>>foo_bar<0>>status_foo<0>>bar_value<0>>#}]' value
from dual)
select
regexp_count(value, 'thing_a<\d*:\d\.\d*>') thing_a, -- count all occurences of thing_a
regexp_replace(value, 'thing_b<(-)>', '0'), -- How to only replace capturing group?
--regexp_substr(regexp_replace(value, 'thing_b<(-)>', '0'),'thing_b<(.)>', 1, 1, NULL, 1), -- assuming this works - how to sum it up? there is no regexp_sum to aggregate the capturing groups?
value
from raw_data;
一些聚合很容易,即对于 thing_a
,regexp_count
工作正常。但是,对于所有其他人,例如 thing_b
,首先将 -
替换为 NaN
,将 F
替换为 0
,将 T
替换为 1
每个捕获组都应该发生。
然后我想总结一下。但是 regexp_sum
似乎不存在。
所需的输出类似于:
thing_a,thing_b,thing_d,...,thing_x
4,0,0,...,3
您可以通过将整个匹配替换为删除捕获组的重新格式化的版本来实现此目的:
regexp_replace(value, '(thing_b)<(-)>', '<0>')
可以使用 Oracle 的内置 SUM() 对这些值求和:
sum(to_number(regexp_substr(regexp_replace(value, '(thing_b)<(-)>', '<0>'),'thing_b<(.)>', 1, 1, NULL, 1)))
完整查询:
with raw_data as(select
'a{ thing_a<1234:1.1>>thing_b<->>thing_c<T>>thing_d<F>>thing_f<F>>thing_g<F>>thing_h<F>>thing_i<F>>thing_x<F>>thing_y<F>>thing_z<F>>#thing_a<234:1.2>>thing_b<->>thing_c<T>>thing_d<F>>thing_f<F>>thing_g<F>>thing_h<F>>thing_i<F>>thing_x<T>>thing_y<F>>thing_z<F>>#thing_a<345:1.3>>thing_b<->>thing_c<T>>thing_d<F>>thing_f<F>>thing_g<F>>thing_h<F>>thing_i<F>>thing_x<T>>thing_y<F>>thing_z<F>>#thing_a<456:1.4>>thing_b<->>thing_c<T>>thing_d<F>>thing_f<F>>thing_g<F>>thing_h<F>>thing_i<F>>thing_x<T>>thing_y<F>>thing_z<F>>#};ADD{some_thing<1234>>some_id<null>>some_stuff<2>>some_date<2013-07-09+02:00>>thing_zz<1>>foo_bar<0>>status_foo<0>>bar_value<0>>#some_thing<234>>some_id<null>>some_stuff<2>>some_date<2013-10-21+02:00>>thing_zz<1>>foo_bar<0>>status_foo<0>>bar_value<0>>#some_thing<345>>some_id<null>>some_stuff<2>>some_date<2013-07-22+02:00>>thing_zz<1>>foo_bar<0>>status_foo<0>>bar_value<0>>#some_thing<456>>some_id<null>>some_stuff<1>>some_date<2014-03-31+02:00>>thing_zz<1>>foo_bar<0>>status_foo<0>>bar_value<0>>#}]' value
from dual)
select
regexp_count(value, 'thing_a<\d*:\d\.\d*>') thing_a, -- count all occurences of thing_a
regexp_replace(value, '(thing_b)<(-)>', '<0>'), -- How to only replace capturing group?
sum(to_number(regexp_substr(regexp_replace(value, '(thing_b)<(-)>', '<0>'),'thing_b<(.)>', 1, 1, NULL, 1))) -- assuming this works - how to sum it up? there is no regexp_sum to aggregate the capturing groups?
from raw_data;